1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
| #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <cmath> #define PB push_back #define MP make_pair #define PII pair<int,int> #define FIR first #define SEC second #define ll long long #define db long double using namespace std; template <class T> inline void rd(T &x) { x=0; char c=getchar(); int f=1; while(!isdigit(c)) { if(c=='-') f=-1; c=getchar(); } while(isdigit(c)) x=x*10-'0'+c,c=getchar(); x*=f; } const int N=(1<<16)+10; const db Pi=acos(-1.0); struct Comp { db a,b; Comp (db a=0,db b=0): a(a),b(b) {} friend Comp operator *(Comp A,Comp B){return Comp(A.a*B.a-A.b*B.b,A.a*B.b+A.b*B.a);} friend Comp operator +(Comp A,Comp B){return Comp(A.a+B.a,A.b+B.b);} friend Comp operator -(Comp A,Comp B){return Comp(A.a-B.a,A.b-B.b);} friend Comp operator /(Comp A,db B){return Comp(A.a/B,A.b/B);} friend Comp operator *(Comp A,db B){return Comp(A.a*B,A.b*B);} Comp conj(){return Comp(a,-b);} }; int rev[N]; void getr(int l){for(int i=1;i<(1<<l);++i) rev[i]=(rev[i>>1]>>1)|((i&1)<<l-1);} void FFT(Comp A[],int len,int f) { for(int i=0;i<len;++i) if(rev[i]<i) swap(A[i],A[rev[i]]); for(int l=2;l<=len;l<<=1) { Comp wn=Comp(cos(2*Pi/l),f*sin(2*Pi/l)); for(int i=0;i<len;i+=l) { Comp w=Comp(1,0); for(int k=i;k<i+(l>>1);++k,w=w*wn) { Comp t1=A[k],t2=A[k+(l>>1)]*w; A[k]=t1+t2,A[k+(l>>1)]=t1-t2; } } } if(f==-1) for(int i=0;i<len;++i) A[i]=A[i]/len; }
Comp A[6][N],B[N]; db frac[6]; int n,m,len; int buc[6]; void dfs(int u,int mx) { if(u==m+1) { db coe=1; for(int i=1;i<=mx;++i) coe*=frac[buc[i]-1]*(buc[i]&1?1:-1); for(int j=0;j<len;++j) { Comp t=Comp(coe,0); for(int i=1;i<=mx;++i) t=t*A[buc[i]][j]; B[j]=B[j]+t; } return; } for(int i=1;i<=mx+1;++i) buc[i]++,dfs(u+1,max(i,mx)),buc[i]--; } int main() { frac[0]=1; for(int i=1;i<=5;++i) frac[i]=frac[i-1]*i; int T,cas=0; rd(T); while(T--) { int num; rd(num),rd(m); n=0; for(int i=1,x;i<=num;++i) { rd(x); for(int j=1;j<=m;++j) A[j][x*j].a+=1; n=max(n,x*m); } len=1; int cnt=0; while(len<=n) len<<=1,cnt++; getr(cnt); for(int j=1;j<=m;++j) FFT(A[j],len,1); dfs(1,0); FFT(B,len,-1); printf("Case #%d:\n",++cas); for(int i=0;i<=n;++i) { db ans=B[i].a/frac[m]; if(ans>0.5) printf("%d: %.0Lf\n",i,ans); } puts(""); for(int j=1;j<=m;++j) for(int i=0;i<len;++i) A[j][i].a=A[j][i].b=0; for(int i=0;i<len;++i) B[i].a=B[i].b=0; } return 0; }
|