http://www.lydsy.com/JudgeOnline/problem.php?id=3771
题意:n个带价值互不相同的物品,每次可以取1、2、3个物品,问能得到的所有的价值和这个价值的方案数(n不明(无意义= =),价值<=40000)
#include <bits/stdc++.h> using namespace std; const int N=200005; int bit[N]; const double PI=acos(-1); struct cp { double r, i; cp(double _r=0, double _i=0) : r(_r), i(_i) {} cp operator + (const cp &a) { return cp(r+a.r, i+a.i); } cp operator - (const cp &a) { return cp(r-a.r, i-a.i); } cp operator * (const cp &a) { return cp(r*a.r-i*a.i, r*a.i+i*a.r); } }; void dft(cp *a, int n, int flag) { for(int i=0; i<n; ++i) if(i<bit[i]) swap(a[i], a[bit[i]]); for(int m=2; m<=n; m<<=1) { cp wn(cos(PI*2.0/m), sin(PI*2.0/m)*flag); int mid=m>>1; for(int i=0; i<n; i+=m) { cp w(1); for(int j=0; j<mid; ++j) { static cp u, v; u=a[i+j], v=a[i+j+mid]*w; a[i+j]=u+v; a[i+j+mid]=u-v; w=w*wn; } } } if(flag==-1) for(int i=0; i<n; ++i) a[i].r/=n; } void fft(int *A, int *B, int *C, int n) { static cp a[N], b[N]; int len=1, bitl=-1; for(; len<n; len<<=1, ++bitl); for(int i=0; i<len; ++i) bit[i]=(bit[i>>1]>>1)|((i&1)<<bitl); for(int i=0; i<len; ++i) a[i].r=A[i], a[i].i=0, b[i].r=B[i], b[i].i=0; dft(a, len, 1); dft(b, len, 1); for(int i=0; i<len; ++i) b[i]=a[i]*b[i]; dft(b, len, -1); for(int i=0; i<len; ++i) C[i]=b[i].r+0.5; } int a[N], b[N], c[N], t[N], ans[N], n, len; void work() { int l=n; for(int i=0; i<l; ++i) ans[i]=a[i]; fft(a, a, t, n*2-1); l=n*2-1; for(int i=0; i<l; ++i) ans[i]+=(t[i]-b[i])>>1; fft(a, t, t, n*3-2); fft(a, b, a, n*3-2); l=n*3-2; for(int i=0; i<l; ++i) ans[i]+=(t[i]-3*a[i]+(c[i]<<1))/6; } int main() { scanf("%d", &len); for(int i=0; i<len; ++i) { int x; scanf("%d", &x); a[x]=1; b[x*2]=1; c[x*3]=1; n=max(x+1, n); } work(); len=n*3-2; for(int i=0; i<len; ++i) if(ans[i]) printf("%d %d\n", i, ans[i]); return 0; }
首先容易得到母函数$A=\sum_{存在价值为i的物品} x^i$
敲完了fft才发现如果直接求母函数的三次方是不对的= =...
妈呀竟然没想到容斥QAQ
设$B = \{A[i]^2\}, C = \{A[i]^3\}$
首先我们对取法分别求:
取1个的方案 $ = A$
取2个的方案 $ = \frac{A^2 - B}{A^{2}_{2}} = \frac{A^2 - B}{2}$
取3个的方案 $ = \frac{A^3 - \frac{3!}{2!1!} AB + \frac{3!}{2!1!} C - C}{A^{3}_{3}} = \frac{A^3 -3AB + 2C}{6}$
(看不懂的建议先去看《组合数学》= =)
然后fft搞搞就行辣= =
时间: 2024-10-10 10:12:28