# bzoj 3771 Triple FFT 生成函数+容斥

## Triple

Time Limit: 20 Sec  Memory Limit: 64 MB
Submit: 847  Solved: 482
[Submit][Status][Discuss]

## Description

“这把斧头，是不是你的？”

“这把斧头，是不是你的？”

“这把斧头，是不是你的？”

“你看看你现在的样子，真是丑陋！”

4
4
5
6
7

## Sample Output

4 1
5 1
6 1
7 1
9 1
10 1
11 2
12 1
13 1
15 1
16 1
17 1
18 1

11有两种方案是4+7和5+6，其他损失值都有唯一方案，例如4=4,5=5,10=4+6,18=5+6+7.

## HINT

然后再去重即可。

 1 #include<cstring>
2 #include<cstdio>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6
7 #define pi acos(-1)
8 #define N 40007
9 using namespace std;
10 inline int read()
11 {
12     int x=0,f=1;char ch=getchar();
13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
14     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
15     return x*f;
16 }
17
18 int n,num,L;
19 int rev[N*6];
20 struct comp
21 {
22     double r,v;
23     comp(){r=v=0.0;}
24     comp(double x,double y){r=x,v=y;}
25     friend inline comp operator+(comp x,comp y){return comp(x.r+y.r,x.v+y.v);}
26     friend inline comp operator-(comp x,comp y){return comp(x.r-y.r,x.v-y.v);}
27     friend inline comp operator*(comp x,comp y){return comp(x.r*y.r-x.v*y.v,x.r*y.v+x.v*y.r);}
28     friend inline comp operator/(comp x,int y){return comp(x.r/y,x.v/y);}
29 }a[N*6],b[N*6],c[N*6];
30
31 void FFT(comp *a,int flag)
32 {
33     for (int i=0;i<num;i++)
34         if (i<rev[i]) swap(a[i],a[rev[i]]);
35     for (int i=1;i<num;i<<=1)
36     {
37         comp wn=comp(cos(pi/i),flag*sin(pi/i));
38         for (int j=0;j<num;j+=(i<<1))
39         {
40             comp w=comp(1,0);
41             for (int k=0;k<i;k++,w=w*wn)
42             {
43                 comp x=a[j+k],y=w*a[j+k+i];
44                 a[j+k]=x+y,a[j+k+i]=x-y;
45             }
46         }
47     }
48     if (flag==-1) for (int i=0;i<num;i++) a[i].r/=num;
49 }
50 int main()
51 {
53     for (int i=1;i<=n;i++)
54     {
56         a[x].r+=1.0;
57         b[x*2].r+=1.0;
58         c[x*3].r+=1.0;
59         up=max(up,x*3);
60     }
61     for (num=1;num<=up;num<<=1,L++);if (L) L--;
62     for (int i=0;i<num;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<L);
63     FFT(a,1),FFT(b,1),FFT(c,1);
64     for (int i=0;i<num;i++)
65         a[i]=a[i]+a[i]*a[i]/2-b[i]/2+a[i]*a[i]*a[i]/6-a[i]*b[i]/2+c[i]/3;
66     FFT(a,-1);
67
68     for (int i=0;i<num;i++)
69     {
70         int x=(int)(a[i].r+0.5);
71         if (x==0) continue;
72         printf("%d %d\n",i,x);
73     }
74 }

posted @ 2018-03-31 14:22  Kaiser-  阅读(111)  评论(0编辑  收藏  举报