BZOJ 4332 FFT+快速幂

思路:

最裸的方程:f[i][j]=Σf[i-1][j-k]*F[k]

诶呦 这不是卷积嘛

f[i]就可以用f[i-1]卷F 求到

但是这样还是很慢

设p[i] 为Σ f[j](1<=j<=i)

发现p可以倍增推

于是  就 倍增一下  就完了...

http://www.cnblogs.com/Skyminer/p/6561689.html

hz神犇的题解写得非常详细..

//By SiriusRen
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N=32888;
const double pi=acos(-1);
int n,M,P,A,O,S,U,L,R[N],F[N],g[N],p[N],t[N],ans;
struct cplxd{double x,y;cplxd(){}cplxd(double X,double Y){x=X,y=Y;}}ca[N],cb[N],cc[N];
cplxd operator+(cplxd a,cplxd b){return cplxd(a.x+b.x,a.y+b.y);}
cplxd operator-(cplxd a,cplxd b){return cplxd(a.x-b.x,a.y-b.y);}
cplxd operator*(cplxd a,cplxd b){return cplxd(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
cplxd operator/(cplxd a,int b){return cplxd(a.x/b,a.y/b);}
void FFT(cplxd *a,int f){
    for(int i=0;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);
    for(int i=1;i<n;i<<=1){
        cplxd wn=cplxd(cos(pi/i),f*sin(pi/i));
        for(int j=0;j<n;j+=(i<<1)){
            cplxd w(1,0);
            for(int k=0;k<i;k++,w=w*wn){
                cplxd x=a[j+k],y=w*a[j+k+i];
                a[j+k]=x+y,a[j+k+i]=x-y;
            }
        }
    }
    if(f==-1)for(int i=0;i<n;i++)a[i]=a[i]/n;
}
void Pw(int *a,int *b,int *c){
    for(int i=0;i<n;i++)ca[i]=cplxd(a[i],0);
    for(int i=0;i<n;i++)cb[i]=cplxd(b[i],0);
    FFT(ca,1),FFT(cb,1);
    for(int i=0;i<n;i++)cc[i]=ca[i]*cb[i];
    FFT(cc,-1);
    for(int i=0;i<=M;i++)c[i]=((int)(0.3+cc[i].x))%P;
}
void pow(int k){
    if(k==1)return;
    pow(k>>1);
    Pw(p,g,t),Pw(g,g,g);
    for(int i=0;i<=M;i++)(p[i]+=t[i])%=P;
    if(k&1){
        Pw(g,F,g);
        for(int i=0;i<=M;i++)(p[i]+=g[i])%=P;
    }
}
signed main(){
    scanf("%d%d%d%d%d%d",&M,&P,&A,&O,&S,&U);
    for(n=1;n<=M*2;n<<=1)L++;
    for(int i=1;i<=n;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
    for(int i=1;i<=M;i++)p[i]=g[i]=F[i]=(i*i*O+S*i+U)%P;
    pow(A),printf("%d\n",p[M]);
}
时间: 2024-10-13 17:26:49

BZOJ 4332 FFT+快速幂的相关文章

【BZOJ 4332】 4332: JSOI2012 分零食 (FFT+快速幂)

4332: JSOI2012 分零食 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 119  Solved: 66 Description 这里是欢乐的进香河,这里是欢乐的幼儿园. 今天是2月14日,星期二.在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着.校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们.听到这个消息,所有同学都安安静静地排好了队,大家都知道,校长不喜欢调皮的孩子. 同学们依次排成了一列,其中有A位小朋友,有三个共同的欢乐

bzoj 4332 FFT型的快速幂(需要强有力的推导公式能力)

有n个小朋友,m颗糖,你要把所有糖果分给这些小朋友. 规则第 i 个小朋友没有糖果,那么他之后的小朋友都没有糖果..如果一个小朋友分到了 xx 个糖果,那么的他的权值是 f(x) = ox^2 + sx + u 没有分到糖果的小朋友的权值是 1 每种方案的权值是各个小朋友权值的乘积 求出所有方案的权值和 设g(i,j)表示前i个小朋友分j个糖果的权值乘积和 很容易得到一个式子 这个显然是一个卷积用FFT就可以处理 但是问题来了 我们如何得到ans呢 n<=1e8  朴素的算法不太行 要想办法优化

【codeforces 623E】dp+FFT+快速幂

题目大意:用$[1,2^k-1]$之间的证书构造一个长度为$n$的序列$a_i$,令$b_i=a_1\ or\ a_2\ or\ ...\ or a_i$,问使得b序列严格递增的方案数,答案对$10^9+7$取模. 数据范围,$n≤1^{18}$,$k≤30000$. 考虑用dp来解决这一题,我们用$f[i][j]$来表示前$i$个数中,使用了$j$个二进制位(注意!并不是前$j$个),那么答案显然为$\sum_{i=0}^{k} \binom{n}{i} \times f[n][i]$. 考虑

P3321 [SDOI2015]序列统计 FFT+快速幂+原根

\(\color{#0066ff}{ 题目描述 }\) 小C有一个集合S,里面的元素都是小于M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合S.小C用这个生成器生成了许多这样的数列.但是小C有一个问题需要你的帮助:给定整数x,求所有可以生成出的,且满足数列中所有数的乘积mod M的值等于x的不同的数列的有多少个.小C认为,两个数列{Ai}和{Bi}不同,当且仅当至少存在一个整数i,满足Ai≠Bi.另外,小C认为这个问题的答案可能很大,因此他只需要你

bzoj(矩阵快速幂)

题意:定义Concatenate(1,N)=1234567……n.比如Concatenate(1,13)=12345678910111213.给定n和m,求Concatenate(1,n)%m. (1=<n<=10^18,1<=m<=10^9) 思路:令f[n]表示Concatenate(1,n).那么有: f[i]=f[i-1]*10+(i-1)+1   1<=i<=9 f[i]=f[i-1]*100+(i-1)+1  10<=i<=99 …… 因此可用矩

bzoj 2179: FFT快速傅立叶 -- FFT

2179: FFT快速傅立叶 Time Limit: 10 Sec  Memory Limit: 259 MB Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果. Sample Input 1 3 4 Sample Output 12 数据范围: n<=60000 HINT #include<map> #include

BZOJ 2179: FFT快速傅立叶

2179: FFT快速傅立叶 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3138  Solved: 1620[Submit][Status][Discuss] Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果. Sample Input 1 3 4 Sample Outpu

bzoj 4000 矩阵快速幂优化DP

建立矩阵,跑快速幂 1 /************************************************************** 2 Problem: 4000 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:32 ms 7 Memory:836 kb 8 ****************************************************************/ 9 10 #inclu

BZOJ 2179 FFT快速傅立叶 ——FFT

[题目分析] 快速傅里叶变换用于高精度乘法. 其实本质就是循环卷积的计算,也就是多项式的乘法. 两次蝴蝶变换. 二进制取反化递归为迭代. 单位根的巧妙取值,是的复杂度成为了nlogn 范德蒙矩阵计算逆矩阵又减轻了拉格朗日插值法的复杂度. 十分神奇. [代码] #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #includ