BZOJ4332: JSOI2012 分零食
来源:互联网 发布:淘宝新店促销活动 编辑:程序博客网 时间:2024/04/28 15:06
首先,因为糖果数M<=10000,最多分给前M个人,所以人数A>M的情况可以视为A=M来做
然后朴素的想法是一个DP,即f[i][j]表示前i个人得到j个糖果的欢乐程度乘积和,有
经观察可以发现,这是一个卷积的形式,可以用FFT优化,因为需要统计
code:
#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;const int maxn = 81000;const int maxd = 18;const double pi = acos(-1);int T,P,n,O,S,U;struct E{ double x,y; E(){x=y=0.0;} E(const double _x,const double _y){x=_x;y=_y;}}zero,w[maxn],g[maxn],f1[maxn],f2[maxn],f[maxn],tt[maxn],t2[maxn];int id[maxn],N,ln;E operator +(E x,E y){return E(x.x+y.x,x.y+y.y);}E operator -(E x,E y){return E(x.x-y.x,x.y-y.y);}E operator *(E x,E y){return E(x.x*y.x-x.y*y.y,x.x*y.y+x.y*y.x);}void DFT(E *s,int sig){ for(int i=0;i<N;i++) if(i<id[i]) swap(s[i],s[id[i]]); for(int m=2;m<=N;m<<=1) { int t=m>>1,tt=N/m; for(int i=0;i<t;i++) { E wn=sig==1?w[i*tt]:w[N-i*tt]; /*E wn; if(sig==1) wn=E(cos(2*pi*i/m),sin(2*pi*i/m)); else wn=E(cos(2*pi*i/m),sin(-2*pi*i/m));*/ for(int j=i;j<N;j+=m) { E tx=s[j],ty=s[j+t]*wn; s[j]=tx+ty; s[j+t]=tx-ty; } } } if(sig==-1) for(int i=0;i<N;i++) s[i].x/=N;}void get_(const int u,const int k){ if(u==1) { for(int i=0;i<N;i++) f[i]=tt[i]=f1[i]; return ; } const int nex=k+1; get_(u>>1,nex); for(int i=0;i<N;i++) t2[i]=f[i]; DFT(t2,1); DFT(tt,1); for(int i=0;i<N;i++) t2[i]=t2[i]*tt[i]; DFT(t2,-1); for(int i=0;i<=T;i++) t2[i].x=((int)(t2[i].x+0.5))%P,t2[i].y=0; for(int i=T+1;i<N;i++) t2[i]=zero; for(int i=0;i<N;i++) f[i]=f[i]+t2[i]; //DFT(tt,1); for(int i=0;i<N;i++) tt[i]=tt[i]*tt[i]; DFT(tt,-1); for(int i=0;i<=T;i++) tt[i].x=((int)(tt[i].x+0.5))%P,tt[i].y=0; for(int i=T+1;i<N;i++) tt[i]=zero; if(u&1) { DFT(tt,1); for(int i=0;i<N;i++) tt[i]=tt[i]*f2[i]; DFT(tt,-1); for(int i=0;i<=T;i++) tt[i].x=((int)(tt[i].x+0.5))%P,tt[i].y=0; for(int i=T+1;i<N;i++) tt[i]=zero; } if(u&1) for(int i=0;i<N;i++) f[i]=f[i]+tt[i];}int main(){ scanf("%d%d%d%d%d%d",&T,&P,&n,&O,&S,&U); O%=P; S%=P; U%=P; if(n>T)n=T; N=1,ln=0; while(N<=(T<<1)) N<<=1,ln++; for(int i=1;i<N;i++) id[i]=(id[i>>1]>>1)|(i&1?(1<<ln-1):0); for(int m=2;m<=N;m<<=1) { int t=m>>1,tt=N/m; for(int i=0;i<t;i++) { w[i*tt]=E(cos(2*pi*i/m),sin(2*pi*i/m)); w[N-i*tt]=E(cos(2*pi*i/m),sin(-2*pi*i/m)); } } g[0]=E(1,0); for(int i=1;i<=T;i++) { int fx=(i*i*O%P+i*S%P+U)%P; f1[i]=f2[i]=E(fx,0); } DFT(f2,1); get_(n,1); DFT(f,1); DFT(g,1); for(int i=0;i<N;i++) g[i]=g[i]*f[i]; DFT(g,-1); int ans=(int)(g[T].x+0.5)%P; printf("%d\n",ans); return 0;}
0 0
- [bzoj4332][JSOI2012]分零食
- BZOJ4332: JSOI2012 分零食
- FFT 【JSOI2012】bzoj4332 分零食
- FFT 【JSOI2012】bzoj4332 分零食
- 「BZOJ4332」「JSOI2012」分零食
- bzoj 4332: JSOI2012 分零食 fft
- 23:17分,项目经理买来宵夜和零食。。
- 教你给零食分个健康等级
- 经典零食!
- 零食王国
- 买零食
- 零食店
- codevs1356 bzoj2746 jsoi2012
- 【JSOI2012】【BZOJ4327】玄武密码
- [BZOJ4327] JSOI2012玄武密码
- BZOJ 4327: JSOI2012 玄武密码
- bzoj4330 JSOI2012 爱之项链
- bzoj4331 JSOI2012 越狱老虎桥
- 二叉树深度优先遍历和广度优先遍历【C++】
- ofbiz方法一 条件查询createConditionList
- Android实现开机自启动某个程序
- ListCycle2
- android.content.ActivityNotFoundException: Unable to find explicit activity class
- BZOJ4332: JSOI2012 分零食
- 深入理解Activity的生命周期
- java实验3.(4)组合的使用例子
- HTTP深入浅出 http请求
- 主力洗盘无非是用这几招,你都知道吗?
- 中断技术学习
- Wireshark将udp包作为rtp包解析
- Linux基础_进度条设计
- 排序之快速排序的java语言简单实现