HDU 6057 – Kanade’s convolution | 2017 Multi-University Training Contest 3

HDU 6057 – Kanade’s convolution | 2017 Multi-University Training Contest 3

大家好,又见面了,我是全栈君。

/*
HDU 6057 - Kanade's convolution [ FWT ]  |  2017 Multi-University Training Contest 3
题意:
	给定两个序列 A[0...2^m-1], B[0...2^m-1]
	求 C[0...2^m-1]	,满足:
		C[k] = ∑[i&j==k] A[i^j] * B[i|j]
	m <= 19
分析:
	看C[k]的形式与集合卷积的形式接近,故转化式子时主要向普通的集合卷积式方向靠
	与三种位运算都相关的结论是 : i^j + i&j = i|j
	设 x = i^j, y = i|j,则显然 k = y-x,且 k 与 x 互成关于 y 的补集,即 k = x^y 
	
	再来关心给定(x,y),符合 x = i^j, y = i|j的(i,j)对的数目
		注意到相同的位 i&j 是确定的,x = i^j 是i和j不同的位的数目,这部分谁是 0 谁是 1 不固定
			故(i,j)对的数目为 2^bits(x)

	此时重写原式: C[k] = ∑ [k == x^y] [k == y-x] A[x]*2^bits(x) * B[y]
	
	设 A'[x] = A[x]*2^bits(x)
	由于 [k == x^y],第二个条件 [k == y-x] 等价于 bits(k) == bits(y) - bits(x)
		C[k] = ∑ [k == x^y] [bits(k) == bits(x) - bits(y)] A'[x] * B[y]
	
	将 A,B,C三个数组按 bits 划分:
		C[bits(k)][k] = ∑ [k == x^y] A[bits(x)][x]*2^bits(x) * B[bits(y)][y]
	
	最后按不同的维度(bits)做 FWT即可
*/
#include <bits/stdc++.h>
using namespace std;
const int MOD = 998244353;
const int N = 1<<20;
int rev2;
long long inv( long long a , long long m)
{
	if (a == 1) return 1;
	return inv(m%a, m) * (m - m/a) % m;
}
void FWT(int a[], int n) {
    for (int d = 1; d < n; d <<= 1)
        for (int m = d<<1, i = 0; i < n; i += m)
            for (int j = 0; j < d; j++)
            {
                int x = a[i+j], y = a[i+j+d];
                a[i+j] = (x+y) % MOD;
                a[i+j+d] = (x-y+MOD) % MOD;
            }
}
void UFWT(int a[], int n) {
    for (int d = 1; d < n; d <<= 1)
        for (int m = d<<1, i = 0; i < n; i += m)
            for (int j = 0; j < d; j++)
            {
                int x = a[i+j], y = a[i+j+d];
                a[i+j] = 1LL*(x+y) * rev2 % MOD;
                a[i+j+d] = (1LL*(x-y)*rev2 % MOD + MOD) % MOD;
            }
}
int a[20][N], b[20][N], c[20][N];
int bits[N];
int m, n;
void init()
{
    rev2 = inv(2, MOD);
    bits[0] = 0;
    for (int i = 1; i < N; i++) bits[i] = bits[i>>1] + (i&1);
}
int main()
{
    init();
    scanf("%d", &m);
    n = 1<<m;
    for (int i = 0; i < n; i++)
    {
        int x; scanf("%d", &x);
        a[bits[i]][i] = 1LL*x * (1<<bits[i]) % MOD;
    }
    for (int i = 0; i < n; i++)
    {
        int x; scanf("%d", &x);
        b[bits[i]][i] = x;
    }
    for (int i = 0; i <= m; i++) FWT(a[i], n);
    for (int i = 0; i <= m; i++) FWT(b[i], n);
    for (int i = 0; i <= m; i++)
        for (int j = i; j <= m; j++)
            for (int k = 0; k < n; k++)
            {
                c[j-i][k] = (c[j-i][k] + 1LL*a[i][k] * b[j][k] % MOD) % MOD;
            }
    for (int i = 0; i <= m; i++) UFWT(c[i], n);
    long long ans = 0, base = 1;
    for (int i = 0; i < n; i++)
    {
        ans = ( ans + c[bits[i]][i] * base % MOD ) % MOD;
        base = base * 1526 % MOD;
    }
    printf("%lld\n", ans);
}

  

转载于:https://www.cnblogs.com/nicetomeetu/p/7291383.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108268.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 大数据应用的现实案例

    大数据应用的现实案例互联网企业拥有大量的线上数据,而且数据量还在快速增长,除了利用大数据提升自己的业务之外,互联网企业已经开始实现数据业务化,利用大数据发现新的商业价值。以阿里巴巴为例,它不仅在不断加强个性化推荐、“千人千面”这种面向消费者的大数据应用,并且还在尝试利用大数据进行智能客户服务,这种应用场景会逐渐从内部应用延展到外部很多企业的呼叫中心之中。在面向商家的大数据应用中,以“生意参谋”为例,超过600万商家在利用“生意参谋”提升自己的电商店面运营水平。除了面向自己的生态之外,阿里巴巴数据业务化也在不断加速,

    2022年6月1日
  • 为什么你学不过动态规划?告别动态规划,谈谈我的经验[通俗易懂]

    为什么你学不过动态规划?告别动态规划,谈谈我的经验[通俗易懂]动态规划难吗?说实话,我觉得很难,特别是对于初学者来说,我当时入门动态规划的时候,是看0-1背包问题,当时真的是一脸懵逼。后来,我遇到动态规划的题,看的懂答案,但就是自己不会做,不知道怎么下手。就像做递归的题,看的懂答案,但下不了手,关于递归的,我之前也写过一篇套路的文章,如果对递归不大懂的,强烈建议看一看:为什么你学不会递归,告别递归,谈谈我的经验对于动态规划,春招秋招时好多题都会用到动态…

    2022年10月29日
  • CMakeLists.txt 语法介绍与实例演练

    CMakeLists.txt 语法介绍与实例演练一、Cmake简介cmake是一个跨平台、开源的构建系统。它是一个集软件构建、测试、打包于一身的软件。它使用与平台和编译器独立的配置文件来对软件编译过程进行控制。二、常用命令1.指定cmake的最小版本cmake_minimum_required(VERSION3.4.1)这行命令是可选的,我们可以不写这句话,但在有些情况下,如果CMakeLists.tx…

    2022年6月21日
  • Android开发入门教程pdf「建议收藏」

    Android开发入门教程pdf「建议收藏」下载地址:网盘下载欢迎进入神秘的android世界!自2008年相关设备进入市场以来,android的发展日新月异,android设备日益繁盛,而其背后开发应用潜藏的经济效益也展露无遗!作为android入门教程,本书将引领大家开发引人入胜的android2.x应用,包括如何设计gui、如何使用gps和访问web服务,以及如何将理念转换成实际应用!本书包含…

    2022年5月20日
  • 记录都有哪些_js常用方法总结

    记录都有哪些_js常用方法总结记录几个常用的js api

    2022年4月22日
  • Android 进行单元測试难在哪-part3

    Android 进行单元測试难在哪-part3

    2022年1月22日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号