zoukankan      html  css  js  c++  java
  • [UOJ310][UNR #2]黎明前的巧克力

    uoj

    description

    给你(n)个数,求从中选出两个交集为空的非空集合异或和相等的方案数模(998244353)

    sol

    其实也就是选出一个集合满足异或和为(0),然后把它分成两半。
    利用生成函数那套理论,就是对于每个(a_i),构造一个多项式(b_i),其中(b_0=1,b_{a_i}=2),然后把这(n)(b)做集合异或卷积。这样我们就得到了一个优秀的(O(na_ilog a_i))的做法辣(雾)
    我们考虑一下(b_0=1,b_{a_i}=2)的这个(b)做一次(FWT)后会发生什么。
    打表发现,(b_0=1)会使得每个位置(+1)(b_{a_i}=2)会使得某些位置(+2),某些位置(-2)。所以最终变换出来的序列里只有(3)(-1)
    我们能不能手动构造一下这若干个(b)的积呢?显然是可以的。我们只需要知道每一个位置上(3)的个数就行了(因为不是(3)就是(-1),知道了(3)的个数也就确定了(-1)的个数)。
    对于每个(a_i),在(b_{a_i})的地方加个(1),然后把这个(b)(FWT)一下,得到的就是每一个位置上(3)的个数减去(-1)的个数。
    所以就可以方便地构造出乘积然后(FWT)回去了。

    code

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int gi(){
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 1<<20;
    const int mod = 998244353;
    int n,mx,len=1,a[N],b[N];
    int fastpow(int a,int b){
    	int res=1;
    	while(b){if(b&1)res=1ll*res*a%mod;a=1ll*a*a%mod;b>>=1;}
    	return res;
    }
    void fwt(int *P,int opt){
    	for (int i=1;i<len;i<<=1)
    		for (int p=i<<1,j=0;j<len;j+=p)
    			for (int k=0;k<i;++k){
    				int x=P[j+k],y=P[j+k+i];
    				P[j+k]=1ll*(x+y)*opt%mod;
    				P[j+k+i]=1ll*(x-y+mod)*opt%mod;
    			}
    }
    int main(){
    	n=gi();int inv2=(mod+1)/2;
    	for (int i=1,x;i<=n;++i)
    		x=gi(),++a[x],mx=max(mx,x);
    	while (len<=mx) len<<=1;
    	fwt(a,1);
    	for (int i=0;i<len;++i){
    		int x=1ll*(a[i]+n)*inv2%mod;
    		a[i]=fastpow(3,x);if((n-x)&1)a[i]=mod-a[i];
    	}
    	fwt(a,inv2);
    	printf("%d
    ",(a[0]-1+mod)%mod);
    	return 0;
    }
    
  • 相关阅读:
    Microsoft.NET User Group
    白话MVP 和 MVVM 【转】
    高效的二分法TOP MAX/TOP MIN分页存贮过程
    策略模式5
    说说我们项目组的例行会议
    合格的项目经理
    说说我们的招聘和面试
    web安全问题汇总
    ASP.NET中常用的优化性能方法
    说说我们安排的培训
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/9255263.html
Copyright © 2011-2022 走看看