FWT|[LOJ]#2340. 「WC2018」州区划分 FWT+欧拉回路

Solution 【FWT|[LOJ]#2340. 「WC2018」州区划分 FWT+欧拉回路】首先对于每个子集判断是否可以单独成一个州,也就是判断是否存在欧拉回路,存在欧拉回路当且仅当图连通且每个点的度数都为偶数。设 s u m S sum_S sumS?为集合 S S S所有元素 w w w之和,若 S S S能成一个州, g S = s u m S p g_S={sum_S}^p gS?=sumS?p,设 f S f_S fS?为集合 S S S所有划分方案的乘积之和,那么 f S = 1 s u m S p ∑ f T g S ? T , T & ( S ? T ) = 0 f_S={1\over {sum_S}^p}\sum f_{T}g_{S-T},T\& (S-T)=0 fS?=sumS?p1?∑fT?gS?T?,T&(S?T)=0。这就是个子集卷积,不过会自己卷自己,要按照 1 1 1的个数分层转移。
不知道为什么,用异或卷积比用或卷积做慢了 10 s 10s 10s……
Code

#include using namespace std; #define LL long long #define pa pair const int inf=2147483647; const int mod=998244353,inv=(mod+1)/2; int read() { int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar(); return x*f; } inline void upd(int&x,int y){x+=y; if(x>=mod)x-=mod; } int Pow(int x,int y) { if(!y)return 1; int t=Pow(x,y>>1),re=(LL)t*t%mod; if(y&1)re=(LL)re*x%mod; return re; } int n,m,p,w[22],f[22][1<<21],g[22][1<<21],s[1<<21],o[1<<21],invs[1<<21],deg[22]; vectorh[22]; int tS; void dfs(int x,int S) { tS|=(1<<(x-1)); for(int i=0; i=0; j--) if(j&(1<>1]+(i&1); for(int i=1; i<=m; i++) { int x=read(),y=read(); h[x].push_back(y),h[y].push_back(x); } for(int i=1; i<=n; i++)w[i]=read(); for(int S=1; S<(1<

    推荐阅读