ACM模板库

ACM模板库


子集卷积

<pre><code class="language-cpp">#include &lt;iostream&gt; using namespace std; const int maxn = (1 &lt;&lt; 18) + 5; int a[50][maxn], b[50][maxn]; int main(){ int n; scanf("%d", &amp;n); int U = (1&lt;&lt;n); for(int i = 1; i &lt; U; i++) popct[i] = popct[i &gt;&gt; 1] + (i &amp; 1); for(int i = 0; i &lt; U; i++) scanf("%d", &amp;a[popct[i]][i]); for(int i = 0; i &lt; U; i++) scanf("%d", &amp;b[popct[i]][i]); for(int i = 0; i &lt;= n; i++) FMT(a[i], 1), FMT(b[i], 1); for(int i = 0; i &lt;= n; i++) for(int j = 0; j &lt;= i; j++) for(int s = 0; s &lt; U; s++) (c[i][s] += 1LL * a[j][s] * b[i-j][s] % mod) %= mod; for(int i = 0; i &lt;= n; i++) FMT(c[i], -1); for(int i = 0; i &lt; U; i++) printf("%d ", c[popct[i]][i]); return 0; } </code></pre> <p>下面是例子代码</p> <pre><code class="language-cpp">#include&lt;bits/stdc++.h&gt; #define rep(i,b,e) for(int i=(b);i&lt;(e);++i) #define dep(i,b,e) for(int i=(b);i&gt;=(e);--i) #define ll long long #define inf 0x3f3f3f3f #define il inline using namespace std; const int mod=998244353; int n,m,u,v,w;ll sum; int g[20][20]; int cnt[1&lt;&lt;18]; ll h[19][1&lt;&lt;18],f[19][1&lt;&lt;18]; void FMT(ll *A,int n,int o=1){ // 快速莫比乌斯变换,求子集和 for(int i=1;i&lt;(1&lt;&lt;n);i&lt;&lt;=1) for(int j=0;j&lt;(1&lt;&lt;n);++j) if(i&amp;j) (A[j]+=A[i^j]*o+mod)%=mod; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin&gt;&gt;n&gt;&gt;m; rep(i,0,n){ rep(j,0,n) g[i][j]=(i==j? 0:inf); } while(m--){ cin&gt;&gt;u&gt;&gt;v&gt;&gt;w; u--;v--; g[u][v]=g[v][u]=min(g[u][v],w); } rep(k,0,n){ rep(i,0,n){ rep(j,0,n) g[i][j]=min(g[i][j],g[i][k]+g[k][j]); } } memset(cnt,0,sizeof(cnt)); memset(h,0,sizeof(h)); memset(f,0,sizeof(f)); rep(i,0,1&lt;&lt;n){ rep(j,0,n) cnt[i]+=((i&amp;(1&lt;&lt;j))&gt;0); } rep(i,1,1&lt;&lt;n){ h[cnt[i]][i]=0x3f3f3f3f3f3f3f3f; rep(j,0,n){ if(i&amp;(1&lt;&lt;j)){ sum=1; rep(k,0,n) if(i&amp;(1&lt;&lt;k)) sum+=g[j][k]; h[cnt[i]][i]=min(h[cnt[i]][i],sum); } } f[cnt[i]][i]=(h[cnt[i]][i]%=mod); } rep(i,0,n+1){ FMT(h[i],n); FMT(f[i],n); } rep(i,1,n+1){ rep(j,0,i+1){ rep(k,0,1&lt;&lt;n) (f[i][k]+=1ll*h[j][k]*f[i-j][k]%mod)%=mod; } FMT(f[i],n,-1); rep(k,0,1&lt;&lt;n) if(cnt[k]!=i) f[i][k]=0; if(i!=n) FMT(f[i],n); } cout&lt;&lt;f[n][(1&lt;&lt;n)-1]&lt;&lt;endl; system("pause"); return 0; }</code></pre>

页面列表

ITEM_HTML