# Bzoj3771 Triple

Time Limit: 20 Sec  Memory Limit: 64 MB
Submit: 563  Solved: 317

## 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.

## Source

拿一把的方案数：$O(n)$直接统计

拿两把的方案数：$ans=(x*x-y)/2$

拿三把的方案数: $ans= (x*x*x-3*x*y+2*z)/6$

1 /*by SilverN*/
2 #include<iostream>
3 #include<algorithm>
4 #include<cstring>
5 #include<cstdio>
6 #include<cmath>
7 #include<vector>
8 #define LL long long
9 using namespace std;
10 const double pi=acos(-1.0);
11 const int mxn=160010;
13     int x=0,f=1;char ch=getchar();
14     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
15     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
16     return x*f;
17 }
18 struct  com{
19     double x,y;
20     com operator + (com b){return (com){x+b.x,y+b.y};}
21     com operator - (com b){return (com){x-b.x,y-b.y};}
22     com operator * (com b){return (com){x*b.x-y*b.y,x*b.y+y*b.x};}
23     com operator / (double v){return (com){x/v,y/v};}
24 }a[mxn],b[mxn],c[mxn];
25 int N,l,rev[mxn];
26 void FFT(com *a,int flag){
27     for(int i=0;i<N;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
28     for(int i=1;i<N;i<<=1){
29         com wn=(com){cos(pi/i),flag*sin(pi/i)};
30         for(int j=0;j<N;j+=i<<1){
31             com w=(com){1,0};
32             for(int k=0;k<i;k++,w=w*wn){
33                 com x=a[k+j],y=w*a[k+j+i];
34                 a[k+j]=x+y;
35                 a[k+j+i]=x-y;
36             }
37         }
38     }
39     if(flag==-1)for(int i=0;i<N;i++) a[i].x/=N;
40     return;
41 }
42 int n,w[mxn];
43 LL ans[mxn],d[mxn];
44 int main(){
45     int i,j,mx=0;
48     int m=mx*3;
49     for(N=1;N<m;N<<=1)l++;
50     for(i=0;i<=N;i++)
51         rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
52     for(i=1;i<=n;i++){++ans[w[i]];}//只拿一把
53     //
54     for(i=1;i<=n;i++)a[w[i]].x+=1;
55     FFT(a,1);
56     for(i=0;i<=N;i++)
57         a[i]=a[i]*a[i];
58     FFT(a,-1);
59     for(i=0;i<=N;i++)d[i]+=(int)(a[i].x+0.3);
60     for(i=1;i<=n;i++)d[w[i]+w[i]]--;
61     for(i=0;i<=N;i++)ans[i]+=d[i]/2;
62     //拿两把
63     memset(a,0,sizeof a);
64     for(i=1;i<=n;i++)a[w[i]].x++;
65     FFT(a,1);
66     for(i=0;i<=N;i++) a[i]=a[i]*a[i]*a[i];
67     FFT(a,-1);
68     for(i=0;i<=N;i++)d[i]=(int)(a[i].x+0.3);
69     memset(a,0,sizeof a);
70     for(i=1;i<=n;i++){
71         a[w[i]].x+=1;
72         b[w[i]+w[i]].x+=1;
73     }
74     FFT(a,1);FFT(b,1);
75     for(i=0;i<=N;i++)c[i]=a[i]*b[i];
76     FFT(c,-1);
77     for(i=0;i<=N;i++)d[i]-=((int)(c[i].x+0.3))*3;
78     for(i=1;i<=n;i++){d[w[i]*3]+=2;}
79     for(i=0;i<=N;i++)ans[i]+=d[i]/6;
80     //拿三把
81     for(i=0;i<=N;i++)
82         if(ans[i])
83             printf("%d %lld\n",i,ans[i]);
84     return 0;
85 }

posted @ 2017-04-20 08:43  SilverNebula  阅读(100)  评论(0编辑  收藏  举报