zoukankan      html  css  js  c++  java
  • bzoj 4332:JSOI2012 分零食

      

    描述

    这里是欢乐的进香河,这里是欢乐的幼儿园。

    今天是2月14日,星期二。在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着。校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们。听到这个消息,所有同学都安安静静地排好了队,大家都知道,校长不喜欢调皮的孩子。

    同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐系数O,S和U。如果有一位小朋友得到了x个糖果,那么她的欢乐程度就是f(x)=Ox^2+Sx+U。

    现在校长开始分糖果了,一共有M个糖果。有些小朋友可能得不到糖果,对于那些得不到糖果的小朋友来说,欢乐程度就是1。如果一位小朋友得不到糖果,那么在她身后的小朋友们也都得不到糖果。(即这一列得不到糖果的小朋友一定是最后的连续若干位)

    所有分糖果的方案都是等概率的。现在问题是:期望情况下,所有小朋友的欢乐程度的乘积是多少?呆呆同学很快就有了一个思路,只要知道总的方案个数T和所有方案下欢乐程度乘积的总和S,就可以得到答案Ans=S/T。现在他已经求出来了T的答案,但是S怎么求呢?他就不知道了。你能告诉他么?

    因为答案很大,你只需要告诉他S对P取模后的结果。

    后记:

    虽然大家都知道,即便知道了T,知道了S对P取模后的结果,也没有办法知道期望情况下,所有小朋友欢乐程度的乘积。但是,当呆呆想到这一点的时候,已经彻底绝望了。

    格式

    输入格式

    第一行有2个整数,分别是M和P。

    第二行有一个整数A,第三行有一个整数O。

    第四行有一个整数S,第五行有一个整数U。

    输出格式

    一个整数S,因为答案可能很大,你只需要输出S 对P取模后的结果。

    看到很多大佬虐这道题,我也很好奇就写了写。

    题里直接给了个生成函数$c$和一个卷积的形式$c^x$,如果题里没有要求拿到糖的人是一个前缀的话直接令$c[0]=1$求一发多项式快速幂就行了。

    但有了限制之后,考虑枚举得到糖的人数,因为不能有人没有糖,令$c[0]=0$。

    设$f[i]$表示只有i个糖时的答案,最后答案为$f[m]$,则

    $$f=sum_{i=1}^{A}c^i$$

    感觉如果模数合适的话应该可以等比数列求和直接做吧。。。开始还以为是一道水题

    但显然这道题不行,那就考虑倍增。

    设$g[i]=c^{2^i},sumg[i]=sum_{i=1}^{2^i}c^i$

    把$A$二进制拆分后用上边两个数组显然是可以求出来的,懒得写了。。。

    注意FFT完往回赋值时只赋$0-m$,不要把FFT完的整个数组都赋回去,调了一晚上不知道哪错了。。。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<cmath>
      6 #define pi acos(-1)
      7 #define N 50005
      8 #define double long double
      9 using namespace std;
     10 struct E
     11 {
     12     double x,y;
     13     E(){;}
     14     E(double _x,double _y)
     15     {
     16         x=_x;y=_y;
     17     }
     18     friend E operator + (E a,E b)
     19     {
     20         return E(a.x+b.x,a.y+b.y);
     21     }
     22     friend E operator - (E a,E b)
     23     {
     24         return E(a.x-b.x,a.y-b.y);
     25     }
     26     friend E operator / (E a,double b)
     27     {
     28         return E(a.x/b,a.y/b);
     29     }
     30     friend E operator * (E a,E b)
     31     {
     32         return E(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
     33     }
     34 }a[N],b[N];
     35 int R[N],n;
     36 void fft(E *a,int f)
     37 {
     38     for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
     39     for(int i=1;i<n;i<<=1)
     40     {
     41         E wn(cos(pi/i),f*sin(pi/i));
     42         for(int j=0;j<n;j+=(i<<1))
     43         {
     44             E w(1,0);
     45             for(int k=0;k<i;k++,w=w*wn)
     46             {
     47                 E x=a[j+k],y=w*a[j+k+i];
     48                 a[j+k]=x+y;a[j+k+i]=x-y;
     49             }
     50         }
     51     }
     52     if(f==-1)
     53     {
     54         for(int i=0;i<n;i++)a[i]=a[i]/(double)n;
     55     }
     56     return ;
     57 }
     58 int m,p,A,O,S,U;
     59 int c[N];
     60 int g[15][N],sg[15][N];
     61 void make(int *a1,int *a2,int *a3)
     62 {
     63     for(int i=0;i<n;i++)a[i].x=a[i].y=b[i].x=b[i].y=0;
     64     for(int i=0;i<n;i++)a[i].x+=a2[i];
     65     for(int i=0;i<n;i++)b[i].x+=a3[i];
     66     fft(a,1);fft(b,1);
     67     for(int i=0;i<n;i++)a[i]=a[i]*b[i];
     68     fft(a,-1);
     69     for(int i=0;i<=m;i++)a1[i]=(int)(a[i].x+0.2);
     70     for(int i=0;i<=m;i++)a1[i]%=p;
     71 }
     72 int gg[N];
     73 void solve()
     74 {
     75     for(int i=0;i<n;i++)g[0][i]=c[i];
     76     for(int i=1;i<=13;i++)make(g[i],g[i-1],g[i-1]);
     77     for(int i=0;i<n;i++)sg[0][i]=c[i];
     78     for(int i=1;i<=13;i++)
     79     {
     80         for(int j=0;j<n;j++)sg[i][j]=sg[i-1][j];
     81         make(gg,sg[i-1],g[i-1]);
     82         for(int j=0;j<n;j++)
     83         {
     84             sg[i][j]=sg[i][j]+gg[j];    
     85             if(sg[i][j]>=p)sg[i][j]-=p;
     86         }
     87     }
     88     return ;
     89 }
     90 int ans[N],now[N];
     91 void pw(int y)
     92 {
     93     now[0]=1;
     94     for(int i=13;i>=0;i--)
     95     {
     96         if(y&(1<<i))
     97         {
     98             make(gg,now,sg[i]);
     99             make(now,now,g[i]);
    100             for(int j=0;j<n;j++)
    101             {
    102                 ans[j]=ans[j]+gg[j];
    103                 if(ans[j]>=p)ans[j]-=p;
    104             }
    105         }
    106     }
    107     return ;
    108 }
    109 int main()
    110 {
    111     scanf("%d%d%d%d%d%d",&m,&p,&A,&O,&S,&U);
    112     S%=p;O%=p;U%=p;
    113     for(int i=1;i<=m;i++)c[i]=(1LL*O*i*i%p+1LL*S*i%p+U)%p;
    114     n=1;int l=0;
    115     while(n<=2*m)n<<=1,l++;
    116     for(int i=0;i<n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(l-1));
    117     if(A>m)A=m;
    118     solve();
    119     pw(A);
    120     printf("%d
    ",ans[m]);
    121     return 0;
    122 }
  • 相关阅读:
    OpenLayer学习之图文标注
    HTML5制作时钟(canvas)
    ADO,NET中简单三层SQLHelper封装介绍
    OpenLayer学习之加载天地图
    ArcGIS Server manger管理页面无法打开问题解决
    Java EE (14) -- SSH配置
    R语言实战读书笔记(一)R语言介绍
    Machine Learning for hackers读书笔记_一句很重要的话
    Machine Learning for hackers读书笔记(十二)模型比较
    Machine Learning for hackers读书笔记(十)KNN:推荐系统
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6618613.html
Copyright © 2011-2022 走看看