# [BZOJ3771] Triple

4
4
5
6
7

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

### 试题分析

$B(x)=\sum_{i=1}^n x^{2a_i}$

$C(x)=\sum_{i=1}^n x^{3a_i}$

FFT计算即可。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>

using namespace std;
#define LL long long
#define Pi 3.1415926535

int x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int MAXN = 1000010;
const int INF = 2147483600;

int l,r[MAXN+1],lim=1;
struct cpx{
double a,b;
cpx (double aa=0,double bb=0){a=aa; b=bb;}
}a[MAXN+1],b[MAXN+1],c[MAXN+1];
int rev[MAXN+1];
cpx operator + (cpx a,cpx b){return cpx(a.a+b.a , a.b+b.b);}
cpx operator - (cpx a,cpx b){return cpx(a.a-b.a , a.b-b.b);}
cpx operator / (cpx a,double b){return cpx(a.a / b , a.b / b);}
cpx operator * (cpx a,double b){return cpx(a.a * b , a.b * b);}
cpx operator * (cpx a,cpx b){return cpx(a.a*b.a - a.b*b.b , a.a*b.b + a.b*b.a);}

inline void FFT(cpx *A,int type){
for(int i=0;i<lim;i++) if(rev[i]>i) swap(A[rev[i]],A[i]);
for(int mid=1;mid<lim;mid<<=1){
cpx Wn(1.0*cos(Pi/mid) , 1.0*type*sin(Pi/mid));
for(int R=mid<<1,j=0;j<lim;j+=R){
cpx w(1,0);
for(int k=0;k<mid;k++,w=w*Wn){
cpx x = A[k+j] , y = w*A[k+j+mid];
A[k+j]=x+y; A[k+j+mid]=x-y;
}
}
} return ;
}
int N,k[MAXN+1],Mx=-INF;

int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
for(int i=1;i<=N;i++) {
b[2*k[i]].a+=1; c[3*k[i]].a+=1;
Mx=max(Mx,3*k[i]);
}
while(lim<=Mx*3) lim<<=1,++l;
for(int i=0;i<lim;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
FFT(a,1); FFT(b,1); FFT(c,1);
for(int i=0;i<lim;i++) a[i]=(a[i]*a[i]*a[i]-3.0*a[i]*b[i]+2.0*c[i])/6.0+(a[i]*a[i]-b[i])/2.0+a[i];
FFT(a,-1);
for(int i=1;i<lim;i++){
LL num=(LL)((a[i].a/lim)+0.5); // cout<<a[i].a<<" "<<lim<<"true"<<endl;
if(num!=0) printf("%d %lld\n",i,num);
}
return 0;
}


posted @ 2018-09-01 16:00  wxjor  阅读(114)  评论(0编辑  收藏  举报