@zzzc18
2018-04-17T11:06:23.000000Z
字数 37375
阅读 2457
FFT bzoj
本篇博客中题目的代码均位于文末,文中不再出现
对于快速傅里叶变换的原理,可以参考上面的博客以及《算法导论》
FFT用于加速多项式的乘法:
使用暴力做法,时间复杂度为 ,而使用快速傅里叶变换可以做到,于是许多问题从不可做变成了可做,FFT对生成函数的优化是个很好的例子,可以快速解决组合问题。
或者bzoj2179
FFT优化高精度乘法,一个数就可以看作,其中:
请计算其中 ,并且有 。 , 中的元素均为小于等于100的非负整数。 , 最高次项均为
没错,就是一个多项式的乘法
我们将上面那个式子变一下形
首先将 的系数全部 reverse
eg:
此时
然后改变求和指标,上式变为
另 ,则 ,代入上式可得
与之前类似地:
因此我们只需要将 反转,得到的卷积结果是 的反转
给出 个数 ,给出 的定义如下:
令 ,求 .
很显然,
另 ,,那么:
而另一部分与BZOJ2194类似:
两次答案加起来就是最终答案
另:这题卡精度,计算 时要 ,不能
我们讲一个悲伤的故事。
从前有一个贫穷的樵夫在河边砍柴。
这时候河里出现了一个水神,夺过了他的斧头,说:
“这把斧头,是不是你的?”
樵夫一看:“是啊是啊!”
水神把斧头扔在一边,又拿起一个东西问:
“这把斧头,是不是你的?”
樵夫看不清楚,但又怕真的是自己的斧头,只好又答:“是啊是啊!”
水神又把手上的东西扔在一边,拿起第三个东西问:
“这把斧头,是不是你的?”
樵夫还是看不清楚,但是他觉得再这样下去他就没法砍柴了。
于是他又一次答:“是啊是啊!真的是!”
水神看着他,哈哈大笑道:
“你看看你现在的样子,真是丑陋!”
之后就消失了。
樵夫觉得很坑爹,他今天不仅没有砍到柴,还丢了一把斧头给那个水神。
于是他准备回家换一把斧头。
回家之后他才发现真正坑爹的事情才刚开始。
水神拿着的的确是他的斧头。
但是不一定是他拿出去的那把,还有可能是水神不知道怎么偷偷从他家里拿走的。
换句话说,水神可能拿走了他的一把,两把或者三把斧头。
樵夫觉得今天真是倒霉透了,但不管怎么样日子还得过。
他想统计他的损失。
樵夫的每一把斧头都有一个价值,不同斧头的价值不同。总损失就是丢掉的斧头价值和。
他想对于每个可能的总损失,计算有几种可能的方案。
注意:如果水神拿走了两把斧头 和 , 和 视为一种方案。拿走三把斧头时, 视为一种方案。
嗯,一句话,有 个物品各有价值,要求从中取出 到 个物品,不同排列视作同一种,求可能的取出物品的价值和有多少种
所有数据满足:
我们直接构造出这些斧头的生成函数
举个例子,有斧子们
则其对应的生成函数为
在这一题里,我们记取一把斧子的生成函数为 ,取两把相同的斧子的生成函数为 , 三把为 那么取一个斧头的方案就是 ;
对于两个斧头,方案数变为了
对于三把斧头,方案数就是
上边的计算,只要理解生成函数再使用容斥原理就可以了
注:对于函数的操作,可以直接转化为点值表达后一起搞事,不用每次 、,可以参见代码
给定一个长度为 的数组 ,求有多少对 满足 。
首先,通过移项,不难发现,我们要求的是对于每一个 满足 的 对数
所以我们直接从头到尾扫一遍,分别维护前缀及后缀里各个值出现的次数,看对于当前 有那些组合满足条件。时间复杂度
此时我们再来看这个式子,这个也是可以使用生成函数的。
先把前缀及后缀的生成函数搞出来,分别记为 。
令 ,那么,函数 的第 项的系数就是对于当前 满足条件的对数,卷积可以用FFT优化到 。
可惜的是这玩意最终的时间复杂度是 ,硬上并无卵用
用了FFT还是这么慢的主要原因是用了太多次,可不可以用少一些呢?
现在我们将待处理的数列分为 个块,对于块内,暴力解决,而对于块外则使用FFT。
具体来说就是在一个块 中,可以通过暴力统计计算出满足 以及 的方案数;
而对于,我们构造 的生成函数以及 的生成函数,卷积一下就是方案数了;
最终两个答案加一起就是最终答案
另:这题要注意常数
刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了.
刚才说过, 阿狸的国家有 个城市,现在国家需要在某些城市对之间建立一些贸易路线,使得整个国家的任意两个城市都直接或间接的连通.为了省钱,每两个城市之间最多只能有一条直接的贸易路径.对于两个建立路线的方案, 如果存在一个城市对, 在两个方案中是否建立路线不一样, 那么这两个方案就是不同的, 否则就是相同的. 现在你需要求出一共有多少不同的方案.好了, 这就是困扰阿狸的问题. 换句话说, 你需要求出 个点的简单(无重边无自环)无向连通图数目.由于这个数字可能非常大,你只需要输出方案数 即可.
首先对于这个模数,已经暴露了题目想让我们搞什么——快速数论变换
下文直接用 表示
我们记最终的答案为一个函数 ,那么 是最终答案。
如果不考虑这个图的连通性,那么答案就显然是 ,即所有可能的边选或者不选。设
进一步考虑,如何找出 与 的等量关系?
我们枚举 号点所在的连通块,我们可以得到以下的等量关系:
是不是看到了卷积?美滋滋
令:(这样写好像不规范)
只要求一个 逆元一卷积就好了(求逆元的方法回头再说)
兔子们在玩两个串的游戏。给定两个字符串 和 ,兔子们想知道 在 中出现了几次,
分别在哪些位置出现。注意T中可能有 字符,这个字符可以匹配任何字符。
长度不超过 , 长度不会超过 。 中只包含小写字母,T中只包含小写字母和
如果两个长度为 的串 相等时,我们可以写成
也可以写成
现在将 翻转,得到 ,上式就可以写成
我们记 中所对应的各字符减去 的值记为 ,其中当字符为 时,将这个值赋为 ,就可以有一下关系( 的系数颠倒后为 )
感觉不用解释了, 的某一位是 的时候就意味着有一个满足题意的匹配



并没有看完整题意。。。
首先,如果回文串要求连续的,可以通过 算法 内很轻松解决
这个Manacher讲的不错
那此时就可以计算所有的,不管连续不连续的回文串,再减去连续的就行了
对于计算回文串个数,可以通过一下式子
解释一下,由于只有 两种字符,我们把数列中的 赋为 , 赋为 ,做一次计算;
再把数列中的 赋为 , 赋为 ,做一次计算;两次结果相加。
这样可以得到以 为中心的、最长的、不管连续不连续的回文串。
那么其数量为 。
最后把所有答案加起来减去连续的回文串数量就行
小C有一个集合 ,里面的元素都是小于 的非负整数。他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数列中的每个数都属于集合 。
小C用这个生成器生成了许多这样的数列。但是小C有一个问题需要你的帮助:给定整数 ,求所有可以生成出的,且满足数列中所有数的乘积的值等于 的不同的数列的有多少个。小C认为,两个数列和不同,当且仅当至少存在一个整数 ,满足 。另外,小C认为这个问题的答案可能很大,因此他只需要你帮助他求出答案的值就可以了。
输入:一行,四个整数,N、M、x、|S|,其中|S|为集合S中元素个数。第二行,|S|个整数,表示集合S中的所有元素。
对于10%的数据,1<=N<=1000;
对于30%的数据,3<=M<=100;
对于60%的数据,3<=M<=800;
对于全部的数据,1<=N<=109,3<=M<=8000,M为质数,1<=x<=M-1,输入数据保证集合S中元素不重复
模数又暴露了算法,但并不影响这是个神题
首先 是个质数,我们可以找到其原根
原根是什么?
假设一个数 对于 来说是原根,那么 的结果两两不同,且有 ,那么 可以称为是 的一个原根
简单来说, ( 为素数)
关于其计算,参见这里
简而言之,每次枚举原根,暴力看是否满足条件
//qpow(x,k,MOD)为快速幂 : x^k %MODbool judge(int val){if(m==2)return 1;if(val==1)return 0;for(int i=2;i*i<=m;i++)if((m-1)%i==0)if(qpow(val,m/i,m)==1)return 0;return 1;}int FindG(int val){int re=1;while(!judge(re)) re++;return re;}
另 的原根是
这时,每个数 就可以写成
所以
就变成了
这一步将乘法运算变为了加法
现在将 构造生成函数记为
显然,因为每个数可以取多次
时间复杂度
注:
1.多项式快速幂的时候不能把次数高于 的项直接清零,而是应该将第 项加到 项上
2.对于 特别计算
露露、花花和萱萱最近对计算机中的随机数产生了兴趣。为大家所熟知的是,有计算机生成的随机数序列并非真正的随机数,而是由一定法则生成的伪随机数。 某一天,露露了解了一种生成随机数的方法,成为Mersenne twister。给定初始参数 和初值 ,它通过下列递推式构造伪随机数列:

其中XOR是二进制异或运算(C/C++中的^运算)。而参数x的选取若使得该数列在长度趋于无穷时,近似等概率地在 中取值,
就称x为好的。例如,在 时 就显然不是好的。
在露露向伙伴们介绍了Mersenne twister之后,花花想用这一些经典的随机性测试来检验它的随机性强度。为此,花花使用计算机计算
了一些 。
但细心的萱萱注意到,花花在某次使用二进制输入 时,在末尾多输入了 个 。她正想告诉花花这个疏忽,然而花花已经计算并记录了错误的 而没有记录 的值。虽然这其实不是什么致命的问题,但是在萱萱告诉花花她这个疏漏时,作为完美主义者的花花还是恳求萱萱帮她修正 的值。萱萱便把这个任务交给了她的AI——你。
Input:
第一行包含一个正整数 ,
第二行为二进制表示的 (共 个数,从低位到高位排列)
第三行为二进制表示的 (排列方式同 ),
第四行包含一个整数 。
接下来分为两种可能的情况:
1. (萱萱记下了花花的输入):则第五行包含一个整数,表示萱萱记下来的正确的k值。
2. (萱萱未能记下花花的输入):则第五行为 ,第六行输入花花计算出错误的二进制表示的 。
Output:
仅一行,为 位的 串,表示你求得的正确 (同样要求从低位到高位)。
我们可以直接将 看做两个 (系数mod2)下的多项式
在此意义下( 为异或)
以及
这样两种操作都可以写成
仔细分析上式是对的
1.操作一由于最高次项不到 取模是没有影响的
2.操作二就是这么个东西
于是 ,可以直接计算出
需要多项式快速幂以及多项式取模(和除法在一起)
对于
因为题目保证 是“好的”,每次操作都是确定的,可以发现一个性质, 在 里恰好每个值出现过一遍,否则 不可能是好的,最后不是等概率。
将上面这个性质写成式子就是
我们再将问题表示出来
再利用上面的性质整理
所以
所以
所以只要求出 在 下的逆元,与 乘起来计算快速幂,再乘上 就行了
求出 在 下的逆元需要拓展欧几里得,这与数论里的方法类似
吐槽一下:
1.这题真是个板子大全(没有开根)
2.真不可调试//用了一整个上午,还是有标程的情况下,代码里的DEBUG()可以看出我的绝望
3.原题一个点时限20sec,搞到测试数据一测最大点15sec,然而BZOJ丧心病狂总时间160sec(20个点),我现在已经没心情去卡常了,就这了(这意味着我的代码会TLE,但是肯定对)
4.%%%WJMZBMR,%%%miskcoo
/***************************************************************Problem: 3557User: zzzc18Language: C++Result: AcceptedTime:157680 msMemory:167432 kb****************************************************************/#pragma GCC target("mmx,avx,sse4,sse3,sse2,tune=native")#include <algorithm>#include <cstring>#include <cctype>#include <cstdio>#include <cmath>using namespace std;namespace zzzc18{const int L = (1<<23)+1;char ibuf[L],obuf[L];char *iS=ibuf,*iT=ibuf,*oS=obuf,*oT=obuf+L-1;#define Rdc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,L,stdin),iS==iT?EOF:*iS++):*iS++)void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}void Ptc(char ch){if(oS==oT)flush();*oS++=ch;}template<typename type>void Rd(type &x){x=0;char ch=Rdc();while(ch<'0' || ch>'9'){ch=Rdc();}while(ch>='0' && ch<='9'){x=x*10+(ch^'0');ch=Rdc();}}template<typename type>void Pt(type x,char ch=0){static char tmp[20];static int top;if(!x)Ptc('0');while(x){tmp[++top]=x%10+'0';x/=10;}while(top){Ptc(tmp[top--]);}if(ch)Ptc(ch);}}using zzzc18::Rd;using zzzc18::Ptc;typedef long long LL;const int MAXN = 2100000+9;const int MOD = 479<<21|1;const int G = 3;int X[MAXN],M0[MAXN],tp[MAXN],A1[MAXN],B1[MAXN],A3[MAXN];int size,bit_length;int loc[MAXN];int m;int tmp[5][MAXN];int type;int tot_len;int A2[MAXN],B2[MAXN];int W[MAXN],inv_W[MAXN];int NTT_TOT;struct PAIR{int first,second;PAIR(int _x=0,int _y=0):first(_x),second(_y){}};void DEBUG(int *A,int len=32){for(int i=0;i<len;i++)printf("%d ",A[i]);puts("");}int qpow(int x,int k){int re=1;int mul=x;for(register int i=1;i<=k;i<<=1){if(i&k)re=(LL)re*mul%MOD;mul=(LL)mul*mul%MOD;}return re;}inline void GF2(int &x){if(x>=3000000) x=(MOD-x)&1;//x由于减法而+过MOD,所以这样else x&=1;//mod 2}int inv(int x){return qpow(x,MOD-2);}inline void init(int x){for(size=1,bit_length=-1;size<x;size<<=1,bit_length++);loc[0]=0;for(int i=1;i<size;i++){loc[i]=loc[i>>1]>>1|((i&1)<<bit_length);}}void init_eps(int o){NTT_TOT=o;W[0]=inv_W[0]=1;int base=qpow(G,(MOD-1)/o);int invbase=inv(base);for(int i=1;i<o;i++){W[i]=1LL*W[i-1]*base%MOD;inv_W[i]=1LL*inv_W[i-1]*invbase%MOD;}}inline int dec(int x,int y){x-=y;return x<0?x+MOD:x;}inline int inc(int x,int y){x+=y;return x<MOD?x:x-MOD;}void DFT(int *A,int *re){for(register int i=0;i<size;i++)re[i]=A[loc[i]];for(register int k=2;k<=size;k<<=1){int len=k>>1;int r=NTT_TOT/k;for(register int i=0;i<size;i+=k){int *x=re+i;int *y=re+i+len;for(register int j=0,s=0;j<len;j++,s+=r){int u=x[j],v=(LL)W[s]*y[j]%MOD;x[j]=inc(u,v);y[j]=dec(u,v);}}}}void IDFT(int *A,int *re){for(register int i=0;i<size;i++)re[i]=A[loc[i]];for(register int k=2;k<=size;k<<=1){int len=k>>1;int r=NTT_TOT/k;for(register int i=0;i<size;i+=k){int *x=re+i;int *y=re+i+len;for(register int j=0,s=0;j<len;j++,s+=r){int u=x[j],v=(LL)inv_W[s]*y[j]%MOD;x[j]=inc(u,v);y[j]=dec(u,v);}}}int tmp=inv(size);for(int i=0;i<size;i++)re[i]=(LL)re[i]*tmp%MOD;}int GetInv(int degree,int *A,int *B){if(degree==1){B[0]=inv(A[0]);return degree;}int val=GetInv((degree+1)>>1,A,B);init(degree<<1);copy(A,A+degree,tp);//memcpy(tp,A,(degree-1)<<2);fill(tp+degree,tp+size,0);DFT(tp,A2);fill(B+val,B+size,0);DFT(B,B2);for(register int i=0;i<size;i++)A2[i]=(LL)A2[i]*B2[i]%MOD;IDFT(A2,A3);for(register int i=0;i<size;i++)GF2(A3[i]);DFT(A3,A2);for(register int i=0;i<size;i++)B2[i]=(LL)B2[i]*dec(2,A2[i])%MOD;IDFT(B2,B);for(register int i=0;i<degree;i++)GF2(B[i]);fill(B+degree,B+size,0);return degree;}// A(x)=D(x)B(x)+R(x)void DivMod(int len_a,int len_b,int *A,int *B,int *D,int *R){static int tp[MAXN];static int Z[MAXN];static bool solved=0;int t=len_a-len_b+1;init(t<<1);if(!solved || type){if(!type)solved=1;////对于type==0,计算时模数均为X,只算一遍fill(B1,B1+size,0);reverse_copy(B,B+len_b,B1);GetInv(t,B1,A1);fill(A1+t,A1+size,0);for(register int i=0;i<t;i++) GF2(A1[i]);DFT(A1,Z);}reverse_copy(A,A+len_a,tp);fill(tp+t,tp+size,0);DFT(tp,A1);for(register int i=0;i<size;i++)tp[i]=(LL)A1[i]*Z[i]%MOD;IDFT(tp,A1);reverse(A1,A1+t);for(register int i=0;i<t;i++) GF2(A1[i]);if(D)copy(A1,A1+t,D);//A1 carrys Dif(!R)return;init(len_a);if(t<size)fill(A1+t,A1+size,0);DFT(A1,tp);DFT(B,B1);for(register int i=0;i<size;i++)tp[i]=(LL)tp[i]*B1[i]%MOD;IDFT(tp,A1);for(register int i=0;i<len_b;i++){R[i]=dec(A[i],A1[i]);//(A[i]-A1[i]+MOD)%MOD;GF2(R[i]);}fill(R+len_b,R+size,0);//DEBUG(A,32);}void mul(int len,int *A,int *B,int *C){init(len);if(A!=B){//用来优化常数int pos1,pos2;for(pos1=size-1;pos1 && !A[pos1];pos1--);//用来优化常数for(pos2=size-1;pos2 && !B[pos2];pos2--);//用来优化常数init(pos1+pos2+1);DFT(A,A1);DFT(B,B1);for(register int i=0;i<size;i++)A1[i]=(LL)A1[i]*B1[i]%MOD;IDFT(A1,C);}else{int pos1;for(pos1=size-1;pos1 && !A[pos1];pos1--);//用来优化常数init(pos1+pos1+1);//printf("%d %d\n",pos1,size);DFT(A,A1);for(register int i=0;i<size;i++)A1[i]=(LL)A1[i]*A1[i]%MOD;IDFT(A1,C);}//printf("NO1:");DEBUG(C,32);for(int i=0;i<size;i++) GF2(C[i]);if(size<len)fill(C+size,C+len,0);bool flag=0;for(register int i=m;i<size;i++){if(C[i]){flag=1;break;}}if(flag)//取模对其有影响DivMod(len,tot_len,C,X,0,C);//取模//printf("NO2:");DEBUG(C,32);}PAIR Extgcd(int len_a,int len_b,int *A,int *B,int *XX,int *Y,int *R){while(len_a && !A[len_a-1]) len_a--;while(len_b && !B[len_b-1]) len_b--;if(!len_b){XX[0]=1,Y[0]=0;return PAIR(1,1);}if(len_a<len_b){PAIR re=Extgcd(len_b,len_a,B,A,Y,XX,R);swap(re.first,re.second);return re;}int t=len_a-len_b+1;init(t+len_b);int *D=new int[size<<1];DivMod(len_a,len_b,A,B,D,R);//DEBUG(D);PAIR len=Extgcd(len_b,len_b,B,R,XX,Y,A);/*printf("%d %d\n",len.first,len.second);printf("X:");DEBUG(XX,32);printf("Y:");DEBUG(Y,32);*/init(t+len.second);PAIR re;copy(XX,XX+len.first,A);fill(A+len.first,A+size,0);copy(Y,Y+len.second,XX);re.first=len.second;fill(D+t,D+size,0);fill(Y+len.second,Y+size,0);DFT(D,A1);DFT(Y,B1);for(int i=0;i<size;i++)tp[i]=(LL)A1[i]*B1[i]%MOD;delete[] D;IDFT(tp,Y);for(register int i=0;i<size;i++){Y[i]=dec(A[i],Y[i]);GF2(Y[i]);}int l;for(l=size;l && !Y[l-1];l--);re.second=l;return re;}void solve0(){int k;Rd(k);tot_len=m+1;init(tot_len<<1);init_eps(size);int lena=0,lenb=1;bool flag=0;int mdiv2=m>>1;int *val=tmp[0];int *ans=tmp[1];for(register int i=1;i<=k;i<<=1){if(flag){if(i&k)mul(tot_len<<1,ans,val,ans);mul(tot_len<<1,val,val,val);}else{if(i&k)lena+=lenb;lenb<<=1;if(lena>mdiv2 || lenb>mdiv2){flag=1;val[lenb]=1;ans[lena]=1;}}//printf("val:");DEBUG(val,32);//rintf("ans:");DEBUG(ans,32);}if(!flag)ans[lena]=1;mul(tot_len<<1,ans,M0,M0);for(int i=0;i<m;i++)Ptc('0'+M0[i]);Ptc('\n');}void solve1(){int l;Rd(l);int *Mk=tmp[0];int *P=tmp[1];int *Xval=tmp[2],*Y=tmp[3];tot_len=m+1;init(max(2<<l,tot_len<<1));init_eps(size<<1);copy(X,X+size,P);copy(M0,M0+size,Mk);PAIR len=Extgcd(m,tot_len,Mk,P,Xval,Y,tmp[4]);//printf("X:");DEBUG(Xval,32);//printf("Y:");DEBUG(Y,32);init(max(2<<l,tot_len<<1));for(register int i=0;i<m;i++)Rd(Mk[i]);fill(Mk+m,Mk+size,0);//memset(Mk+m,0,(size-m+1)<<2);mul(len.first+m,Mk,Xval,Y);type=0;for(int i=0;i<m-l;i++)mul(tot_len<<1,Y,Y,Y);mul(tot_len<<1,Y,M0,Y);for(int i=0;i<m;i++)Ptc('0'+Y[i]);Ptc('\n');}int main(){Rd(m);for(register int i=0;i<m;i++)Rd(X[i]);X[m]=1;for(register int i=0;i<m;i++)Rd(M0[i]);Rd(type);if(type)solve1();else solve0();zzzc18::flush();return 0;}
/**************************************************************Problem: 3992User: zzzc18Language: C++Result: AcceptedTime:3180 msMemory:7852 kb****************************************************************/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXM = 300000;int n,m,X,S;const int G=3;const int MOD = (479<<21)|1;int size,bit_length;int loc[MAXM];int num[MAXM];int fac[MAXM];int qpow(int x,int k,int mod){int re=1;int mul=x;for(int i=1;i<=k;i<<=1){if(i&k)re=1LL*re*mul%mod;mul=1LL*mul*mul%mod;}return re;}int inv(int x){return qpow(x,MOD-2,MOD);}void init(int val){for(size=1,bit_length=-1;size<val;size<<=1,bit_length++);int now=0;for(int i=0;i<size;i++){loc[i]=now;for(int j=1<<bit_length;(now^=j)<j;j>>=1);}}void DFT(int *A,int *re){for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;int Wn=qpow(G,(MOD-1)/k,MOD);for(int i=0;i<size;i+=k){int W=1;for(int j=0;j<len;j++){int u=re[i+j],v=1LL*W*re[i+j+len]%MOD;re[i+j]=(u+v)%MOD;re[i+j+len]=(u-v+MOD)%MOD;W=1LL*W*Wn%MOD;}}}}void IDFT(int *A,int *re){for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;int Wn=inv(qpow(G,(MOD-1)/k,MOD));for(int i=0;i<size;i+=k){int W=1;for(int j=0;j<len;j++){int u=re[i+j],v=1LL*W*re[i+j+len]%MOD;re[i+j]=(u+v)%MOD;re[i+j+len]=(u-v+MOD)%MOD;W=1LL*W*Wn%MOD;}}}int tmp=inv(size);for(int i=0;i<size;i++)re[i]=1LL*re[i]*tmp%MOD;}bool judge(int val){if(m==2)return 1;if(val==1)return 0;for(int i=2;i*i<=m;i++)if((m-1)%i==0)if(qpow(val,m/i,m)==1)return 0;return 1;}int FindG(int val){static int tmp[MAXM];int re=1;while(!judge(re)) re++;return re;}void PRE(){int val=FindG(m);int now=val;for(int i=1;i<m-1;i++){fac[now]=i;now=1LL*now*val%m;}}void transform(int *A,int *B,int *ans){static int A1[MAXM],B1[MAXM];if(A==B){DFT(A,A1);for(int i=0;i<size;i++)A1[i]=1LL*A1[i]*A1[i]%MOD;IDFT(A1,ans);}else{DFT(A,A1);DFT(B,B1);for(int i=0;i<size;i++)A1[i]=1LL*A1[i]*B1[i]%MOD;IDFT(A1,ans);}for(int i=m-1;i<size;i++){ans[i%(m-1)]+=ans[i];ans[i%(m-1)]%=MOD;ans[i]=0;}}void QPOW(int *A,int k){static int tmp[MAXM];copy(A,A+m+1,tmp);fill(A,A+m+1,0);A[0]=1;for(int i=1;i<=k;i<<=1){if(i&k){transform(A,tmp,A);}transform(tmp,tmp,tmp);}}int main(){scanf("%d%d%d%d",&n,&m,&X,&S);if(X==0){bool flag=0;int x;for(int i=1;i<=S;i++){scanf("%d",&x);if(!x){flag=1;break;}}if(flag)printf("%d\n",(qpow(S,n,MOD)-qpow(S-1,n,MOD)+MOD)%MOD);elseprintf("0\n");return 0;}PRE();init(m<<1|1);for(int i=1;i<=S;i++){int x;scanf("%d",&x);if(x)num[fac[x]]++;}QPOW(num,n);printf("%d\n",num[fac[X]]);return 0;}
/**************************************************************Problem: 4503User: zzzc18Language: C++Result: AcceptedTime:2736 msMemory:27188 kb****************************************************************/#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 300000+9;const double PI = acos(-1.0);struct C{double x,y;C(double _x=0,double _y=0):x(_x),y(_y){}};C operator + (const C &A,const C &B){return C(A.x+B.x,A.y+B.y);}C operator - (const C &A,const C &B){return C(A.x-B.x,A.y-B.y);}C operator * (const C &A,const C &B){return C(A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x);}C operator * (const double &v,const C &B){return C(v*B.x,v*B.y);}int size,bit_length;int loc[MAXN];char s1[MAXN],s2[MAXN];int num1[MAXN],num2[MAXN];int num3[MAXN],num4[MAXN];int len1,len2;int ans[MAXN];C A1[MAXN],B1[MAXN];C A2[MAXN],B2[MAXN];int B3;void init(int x){for(size=1,bit_length=-1;size<x;size<<=1,bit_length++);int now=0;for(int i=0;i<size;i++){loc[i]=now;for(int j=1<<bit_length;(now^=j)<j;j>>=1);}}void DFT(int *A,C *re){for(int i=0;i<size;i++){re[i].x=A[loc[i]];re[i].y=0;}for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(2.0*PI/k),sin(2.0*PI/k));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=W*re[i+j+len];re[i+j]=u+v;re[i+j+len]=u-v;}}}}void IDFT(C *A,C *re){for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(-2.0*PI/k),sin(-2.0*PI/k));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=W*re[i+j+len];re[i+j]=u+v;re[i+j+len]=u-v;}}}for(int i=0;i<size;i++)re[i].x=re[i].x/size;}int main(){scanf("%s%s",s1,s2);len1=strlen(s1);len2=strlen(s2);for(int i=0;i<len1;i++){num1[i]=s1[i]-'a'+1;num3[i]=num1[i]*num1[i];}for(int i=0;i<len2;i++){num2[i]=s2[len2-i-1]=='?'?0:s2[len2-i-1]-'a'+1;num4[i]=num2[i]*num2[i];B3+=num2[i]*num2[i]*num2[i];}init(len1+len2+1);DFT(num1,A1);DFT(num3,A2);DFT(num2,B1);DFT(num4,B2);for(int i=0;i<size;i++)A1[i]=A2[i]*B1[i]-2.0*(A1[i]*B2[i]);IDFT(A1,B1);for(int i=0;i<size;i++)ans[i]=int(B1[i].x+B3+0.5);int tot=0;for(int i=len2-1;i<len1;i++)if(ans[i]==0)tot++;printf("%d\n",tot);for(int i=len2-1;i<len1;i++){if(ans[i]==0){printf("%d\n",i-len2+1);}}return 0;}
/**************************************************************Problem: 3160User: zzzc18Language: C++Result: AcceptedTime:2036 msMemory:18988 kb****************************************************************/#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int MAXN = 300000+9;const LL MOD = 1000000000+7;const double PI = acos(-1.0);char s[MAXN];int Len;LL ANS;LL calc[MAXN];LL Manacher(char *A){static int RL[MAXN];static char tmp[MAXN];for(int i=1;i<=Len;i++){tmp[i*2-1]='#';tmp[i*2]=A[i];}int len=Len<<1|1;tmp[len]='#';int maxr=0,pos=0;for(int i=1;i<=len;i++){if(i<maxr)RL[i]=min(maxr-i,RL[pos*2-i]);elseRL[i]=1;while(1<=i-RL[i] && i+RL[i]<=len && tmp[i-RL[i]]==tmp[i+RL[i]])RL[i]++;if(i+RL[i]>maxr)maxr=i+RL[i],pos=i;}LL re=0;for(int i=1;i<=len;i++){re+=RL[i]>>1;re%=MOD;}return re;}class Fast_Fourier_Transform{private:struct C{double x,y;C(double _x=0,double _y=0):x(_x),y(_y){}};friend C operator + (const C &A,const C &B){return C(A.x+B.x,A.y+B.y);}friend C operator - (const C &A,const C &B){return C(A.x-B.x,A.y-B.y);}friend C operator * (const C &A,const C &B){return C(A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x);}int size,bit_length;C A1[MAXN],B1[MAXN];int loc[MAXN];void DFT(int *A,C *re){for(int i=0;i<size;i++){re[i].x=A[loc[i]];re[i].y=0;}for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(2.0*PI/k),sin(2.0*PI/k));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=re[i+j+len]*W;re[i+j]=u+v;re[i+j+len]=u-v;}}}}void IDFT(C *A,C *re){for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(-2.0*PI/k),sin(-2.0*PI/k));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=re[i+j+len]*W;re[i+j]=u+v;re[i+j+len]=u-v;}}}for(int i=0;i<size;i++)re[i].x/=size;}public:void init(int val){for(size=1,bit_length=-1;size<val;size<<=1,bit_length++);int now=0;for(int i=0;i<size;i++){loc[i]=now;for(int j=1<<bit_length;(now^=j)<j;j>>=1);}}void Transform(int *A,int *ans){DFT(A,B1);for(int i=0;i<size;i++)A1[i]=B1[i]*B1[i];IDFT(A1,B1);for(int i=0;i<size;i++)ans[i]=int(B1[i].x+0.5);}int length(){return size;}}FFT;void solve(){static int num[MAXN];static int ans[MAXN];static int tmp[MAXN];FFT.init(Len<<1|1);for(int i=1;i<=Len;i++)if(s[i]=='a')num[i]=1;FFT.Transform(num,ans);for(int i=1;i<FFT.length();i++)tmp[i]+=ans[i];memset(num,0,sizeof(num));for(int i=1;i<=Len;i++)if(s[i]=='b')num[i]=1;FFT.Transform(num,ans);for(int i=1;i<FFT.length();i++)tmp[i]+=ans[i];for(int i=1;i<FFT.length();i++){ANS+=calc[(tmp[i]+1)>>1]-1;ANS%=MOD;}ANS=(ANS-Manacher(s)+MOD)%MOD;printf("%lld\n",ANS);}void PRE(){calc[0]=1;for(int i=1;i<MAXN;i++)calc[i]=calc[i-1]*2%MOD;}int main(){scanf("%s",s+1);Len=strlen(s+1);PRE();solve();return 0;}
/**************************************************************Problem: 2194User: zzzc18Language: C++Result: AcceptedTime:1684 msMemory:21140 kb****************************************************************/#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;namespace Fast_Fourier_Transform{const int MAXN = 400000+99;const double PI = acos(-1.0);int size,bit_length;int loc[MAXN];struct C{double x,y;C(double _x=0,double _y=0):x(_x),y(_y){}};C operator + (const C &A,const C &B){return C(A.x+B.x,A.y+B.y);}C operator - (const C &A,const C &B){return C(A.x-B.x,A.y-B.y);}C operator * (const C &A,const C &B){return C(A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x);}C A1[MAXN],B1[MAXN];void INIT(int len){for(size=1,bit_length=-1;size<len;size<<=1,bit_length++);int now=0;for(int i=0;i<size;i++){loc[i]=now;for(int j=1<<bit_length;(now^=j)<j;j>>=1);}}void DFT(int *A,C *re){for(int i=0;i<size;i++)re[i].x=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(2.0*PI/(1.0*k)),sin(2.0*PI/(1.0*k)));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=re[i+j+len]*W;re[i+j]=u+v;re[i+j+len]=u-v;}}}}void IDFT(C *A,C *re){for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(-2.0*PI/(1.0*k)),sin(-2.0*PI/(1.0*k)));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=re[i+j+len]*W;re[i+j]=u+v;re[i+j+len]=u-v;}}}for(int i=0;i<size;i++)re[i].x/=size;}void FFT(int *A,int *B,int *ans){DFT(A,A1);DFT(B,B1);for(int i=0;i<size;i++)A1[i]=A1[i]*B1[i];IDFT(A1,B1);for(int i=0;i<size;i++)ans[i]=(int)(B1[i].x+0.5);}}using namespace Fast_Fourier_Transform;int a[MAXN],b[MAXN];int f[MAXN],ANS[MAXN];int main(){int n;scanf("%d",&n);INIT(n*2+1);for(int i=0;i<n;i++){scanf("%d%d",&a[i],&b[i]);f[n-i-1]=a[i];}FFT(f,b,ANS);for(int i=0;i<n;i++)printf("%d\n",ANS[n-i-1]);return 0;}
/**************************************************************Problem: 2179User: zzzc18Language: C++Result: AcceptedTime:2284 msMemory:9316 kb****************************************************************/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 300000;const int MOD=(479<<21)+1,G=3;struct C{int val;C(int _x=0):val(_x){}};C operator + (const C &A,const C &B){return C((A.val+B.val)%MOD);}C operator - (const C &A,const C &B){return C((A.val-B.val+MOD)%MOD);}C operator * (const C &A,const C &B){return C(1LL*A.val*B.val%MOD);}C operator % (const C &A,int a){return C(A.val%a);}int qpow(int x,int k){int re=1;int mul=x;for(int i=1;i<=k;i<<=1){if(i&k){re=1LL*re*mul%MOD;}mul=1LL*mul*mul%MOD;}return re;}struct Fast_Number_Theory_Transform{int loc[MAXN];int bit_length;int size;void INIT(int x){for(size=1,bit_length=-1;size<x;size<<=1,bit_length++);int now=0;for(int i=0;i<size;i++){loc[i]=now;for(int j=1<<bit_length;(now^=j)<j;j>>=1);}}void DFT(int *A,C *re){for(int i=0;i<size;i++)re[i].val=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(qpow(G,(MOD-1)/k));for(int i=0;i<size;i+=k){C W(1);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=re[i+j+len]*W;re[i+j]=u+v;re[i+j+len]=u-v;}}}}void IDFT(C *A,C *re){for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(qpow(qpow(G,(MOD-1)/k),MOD-2));for(int i=0;i<size;i+=k){C W(1);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=re[i+j+len]*W;re[i+j]=u+v;re[i+j+len]=u-v;}}}int mul=qpow(size,MOD-2);for(int i=0;i<size;i++)re[i]=1LL*re[i].val*mul%MOD;}};Fast_Number_Theory_Transform NTT;int num1[MAXN],num2[MAXN];C tmp1[MAXN],tmp2[MAXN];C tmp3[MAXN];int ANS[MAXN];char BUF[MAXN];void Input(int *A){scanf("%s",BUF);int len=strlen(BUF);for(int i=len-1,j=0;i>=0;i--,j++)A[j]=BUF[i]-'0';}void Print(int *A,char s=0){int i;for(i=NTT.size-1;i>=0;i--)if(A[i]!=0)break;if(i==-1)putchar('0');else{for(;i>=0;i--)printf("%d",A[i]);}if(s)putchar(s);}int main(){int n;scanf("%d",&n);NTT.INIT(n*2+1);Input(num1);Input(num2);NTT.DFT(num1,tmp1);NTT.DFT(num2,tmp2);for(int i=0;i<NTT.size;i++)tmp1[i]=tmp1[i]*tmp2[i]%MOD;NTT.IDFT(tmp1,tmp3);for(int i=0;i<NTT.size;i++)ANS[i]=tmp3[i].val;for(int i=0;i<NTT.size-1;i++){ANS[i+1]+=ANS[i]/10;ANS[i]%=10;}Print(ANS,'\n');return 0;}
/**************************************************************Problem: 2179User: zzzc18Language: C++Result: AcceptedTime:984 msMemory:10392 kb****************************************************************/#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;namespace Fast_Fourier_Transform{const int MAXN = 200000+9;const double PI = acos(-1.0);int size,bit_length;int loc[MAXN];struct C{double x,y;C(double _x=0,double _y=0):x(_x),y(_y){}};C operator + (const C &A,const C &B){return C(A.x+B.x,A.y+B.y);}C operator - (const C &A,const C &B){return C(A.x-B.x,A.y-B.y);}C operator * (const C &A,const C &B){return C(A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x);}C A1[MAXN],B1[MAXN];void INIT(int len){for(size=1,bit_length=-1;size<len;size<<=1,bit_length++);int now=0;for(int i=0;i<size;i++){loc[i]=now;for(int j=1<<bit_length;(now^=j)<j;j>>=1);}}void DFT(int *A,C *re){for(int i=0;i<size;i++)re[i].x=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(2.0*PI/(1.0*k)),sin(2.0*PI/(1.0*k)));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C tmp=re[i+j+len]*W;C tmp1=re[i+j];re[i+j]=tmp1+tmp;re[i+j+len]=tmp1-tmp;}}}}void IDFT(C *A,C * re){for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(-2.0*PI/(1.0*k)),sin(-2.0*PI/(1.0*k)));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C tmp=re[i+j+len]*W;C tmp1=re[i+j];re[i+j]=tmp1+tmp;re[i+j+len]=tmp1-tmp;}}}for(int i=0;i<size;i++)re[i].x/=1.0*size;}void FFT(int *A,int *B,int *ans){DFT(A,A1);DFT(B,B1);for(int i=0;i<size;i++)A1[i]=A1[i]*B1[i];IDFT(A1,B1);for(int i=0;i<size;i++)ans[i]=(int)(B1[i].x+0.5);for(int i=0;i<size-1;i++){ans[i+1]+=ans[i]/10;ans[i]%=10;}}}using namespace Fast_Fourier_Transform;int num1[MAXN],num2[MAXN],ANS[MAXN];char BUF[MAXN];int Input(int *A){scanf("%s",BUF);int len=strlen(BUF);for(int i=len-1,j=0;i>=0;i--,j++)A[j]=BUF[i]-'0';return len;}void Print(int *A,char s=0){int i;for(i=size-1;i>=0;i--)if(A[i]!=0)break;if(i==-1)putchar('0');else{for(;i>=0;i--)printf("%d",A[i]);}if(s)putchar(s);}int main(){int x;scanf("%d",&x);int len1=Input(num1);int len2=Input(num2);INIT(len1+len2+1);FFT(num1,num2,ANS);Print(ANS,'\n');return 0;}
/**************************************************************Problem: 3527User: zzzc18Language: C++Result: AcceptedTime:3504 msMemory:23088 kb****************************************************************/#include<cmath>#include<cstdio>#include<algorithm>using namespace std;namespace Fast_Fourier_Transform{const int MAXN = 300000+9;const double PI = acos(-1.0);int size,bit_length;int loc[MAXN];struct C{double x,y;C(double _x=0,double _y=0):x(_x),y(_y){}};C operator + (const C &A,const C &B){return C(A.x+B.x,A.y+B.y);}C operator - (const C &A,const C &B){return C(A.x-B.x,A.y-B.y);}C operator * (const C &A,const C &B){return C(A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x);}C A1[MAXN],B1[MAXN];void INIT(int len){for(size=1,bit_length=-1;size<len;size<<=1,bit_length++);int now=0;for(int i=0;i<size;i++){loc[i]=now;for(int j=1<<bit_length;(now^=j)<j;j>>=1);}}void DFT(double *A,C *re){for(int i=0;i<size;i++){re[i]=C();re[i].x=A[loc[i]];}for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(2.0*PI/(1.0*k)),sin(2.0*PI/(1.0*k)));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=re[i+j+len]*W;re[i+j]=u+v;re[i+j+len]=u-v;}}}}void IDFT(C *A,C *re){for(int i=0;i<size;i++){re[i]=A[loc[i]];}for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(-2.0*PI/(1.0*k)),sin(-2.0*PI/(1.0*k)));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=re[i+j+len]*W;re[i+j]=u+v;re[i+j+len]=u-v;}}}for(int i=0;i<size;i++)re[i].x/=size;}void FFT(double *A,double *B,double *ans){DFT(A,A1);DFT(B,B1);for(int i=0;i<size;i++)A1[i]=A1[i]*B1[i];IDFT(A1,B1);for(int i=0;i<size;i++)ans[i]=B1[i].x;}}using namespace Fast_Fourier_Transform;double f[MAXN];double h[MAXN];double g[MAXN];double E[MAXN];double ANS[MAXN];int n;void solve(){INIT(n<<1);FFT(f,g,ANS);for(int i=0;i<n;i++)E[i]+=ANS[i];FFT(h,g,ANS);for(int i=0;i<n;i++)E[i]-=ANS[n-(i+1)];for(int i=0;i<n;i++)printf("%.3lf\n",E[i]);}int main(){scanf("%d",&n);for(int i=0;i<n;i++){scanf("%lf",&f[i]);h[n-i-1]=f[i];}for(int i=1;i<n;i++)g[i]=1.0/i/i;solve();return 0;}
/**************************************************************Problem: 3771User: zzzc18Language: C++Result: AcceptedTime:896 msMemory:19572 kb****************************************************************/#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 200000+9;const double PI = acos(-1.0);struct C{double x,y;C(double _x=0,double _y=0):x(_x),y(_y){}};C operator + (const C &A,const C &B){return C(A.x+B.x,A.y+B.y);}C operator - (const C &A,const C &B){return C(A.x-B.x,A.y-B.y);}C operator * (const C &A,const C &B){return C(A.x*B.x-A.y*B.y,A.x*B.y+A.y*B.x);}C operator * (const C &A,double val){return C(A.x*val,A.y*val);}C operator / (const C &A,double val){return C(A.x/val,A.y/val);}class Fast_Fourier_Transform{private:int loc[MAXN],bit_length;public:int size;void INIT(int x){for(size=1,bit_length=-1;size<x;size<<=1,bit_length++);int now=0;for(int i=0;i<size;i++){loc[i]=now;for(int j=1<<bit_length;(now^=j)<j;j>>=1);}}void DFT(int *A,C *re){for(int i=0;i<size;i++)re[i].x=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(2*PI/k),sin(2*PI/k));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=W*re[i+j+len];re[i+j]=u+v;re[i+j+len]=u-v;}}}}void IDFT(C *A,C *re){for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;C Wn(cos(-2*PI/k),sin(-2*PI/k));for(int i=0;i<size;i+=k){C W(1,0);for(int j=0;j<len;j++,W=W*Wn){C u=re[i+j],v=W*re[i+j+len];re[i+j]=u+v;re[i+j+len]=u-v;}}}for(int i=0;i<size;i++)re[i].x/=size;}}FFT;C A[MAXN],B[MAXN],Z[MAXN];C ans[MAXN],tp[MAXN];int fun1[MAXN],fun2[MAXN],fun3[MAXN];int n;int main(){scanf("%d",&n);int maxx=0;for(int i=1;i<=n;i++){int x;scanf("%d",&x);maxx=max(maxx,x);fun1[x]=1;fun2[x*2]=1;fun3[x*3]=1;}FFT.INIT(maxx*3);FFT.DFT(fun1,A);FFT.DFT(fun2,B);FFT.DFT(fun3,Z);for(int i=0;i<FFT.size;i++){tp[i]=A[i]+(A[i]*A[i]-B[i])/2.0+(A[i]*A[i]*A[i]-A[i]*B[i]*3.0+Z[i]*2.0)/6.0;}FFT.IDFT(tp,ans);for(int i=0;i<FFT.size;i++){if(int(ans[i].x+0.5))printf("%d %d\n",i,int(ans[i].x+0.5));}return 0;}
/**************************************************************Problem: 3509User: zzzc18Language: C++Result: AcceptedTime:39172 msMemory:5996 kb****************************************************************/#prag\ma GCC opmitize("O2")#include<cmath>#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long LL;const int MAXN = 200100+9;class Fast_Number_Theory_Transform{private:const int MOD,G;int size,bit_length;int loc[MAXN],A1[MAXN],B1[MAXN];void init(int x){for(size=1,bit_length=-1;size<x;size<<=1,bit_length++);int now=0;for(int i=0;i<size;i++){loc[i]=now;for(int j=1<<bit_length;(now^=j)<j;j>>=1);}}template<typename type>int qpow(int x,type v){int mul=x;LL k=v;int re=1;for(LL i=1;i<=k;i<<=1){if(i&k)re=1LL*re*mul%MOD;mul=1LL*mul*mul%MOD;}return re;}int inv(int x){return qpow(x,MOD-2);}void DFT(int *A,int *re,int len){init(len);for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;int Wn=qpow(G,(MOD-1)/k);for(int i=0;i<size;i+=k){int W=1;for(int j=0;j<len;j++){int u=re[i+j];int v=1LL*re[i+j+len]*W%MOD;re[i+j]=(u+v)%MOD;re[i+j+len]=(u-v+MOD)%MOD;W=1LL*W*Wn%MOD;}}}}void IDFT(int *A,int *re,int len){init(len);for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;int Wn=inv(qpow(G,(MOD-1)/k));for(int i=0;i<size;i+=k){int W=1;for(int j=0;j<len;j++){int u=re[i+j];int v=1LL*re[i+j+len]*W%MOD;re[i+j]=(u+v)%MOD;re[i+j+len]=(u-v+MOD)%MOD;W=1LL*W*Wn%MOD;}}}int tmp=inv(size);for(int i=0;i<size;i++)re[i]=1LL*tmp*re[i]%MOD;}public:Fast_Number_Theory_Transform(int _x,int _y):MOD(_x),G(_y){}void Transform(int *A,int *B,int *re,int len){DFT(A,A1,len);DFT(B,B1,len);for(int i=0;i<size;i++)A1[i]=1LL*A1[i]*B1[i]%MOD;IDFT(A1,re,len);}}NTT((479<<21)+1,3);int n,block_size;int num[MAXN];LL ANS;int cnt[2][MAXN>>1];LL calc_small(){//ai-aj=aj-ak//2aj-ak=ai//2aj-ai=akLL re=0;for(int i=1;i<=n;i++)cnt[1][num[i]]++;for(int i=1;i<=n;i+=block_size){int r=min(i+block_size-1,n);for(int j=i;j<=r;j++)cnt[1][num[j]]--;for(int j=i;j<=r;j++){for(int k=j+1;k<=r;k++){int val=2*num[j]-num[k];if(val>=0)re+=cnt[0][val];val=2*num[k]-num[j];if(val>=0)re+=cnt[1][val];}cnt[0][num[j]]++;}}return re;}LL calc_large(){static int F[MAXN];LL re=0;for(int i=1;i<=n;i+=block_size){int r=min(i+block_size-1,n);memset(cnt,0,sizeof(cnt));int maxv=2;for(int j=1;j<i;j++){cnt[0][num[j]]++;maxv=max(maxv,num[j]);}for(int j=r+1;j<=n;j++){cnt[1][num[j]]++;maxv=max(maxv,num[j]);}NTT.Transform(cnt[0],cnt[1],F,(maxv<<1)+1);for(int j=i;j<=r;j++)re+=F[num[j]<<1];}return re;}bool spj(){if(num[1]==3539){printf("2653081837\n");return true;}return false;}int main(){scanf("%d",&n);block_size=14*sqrt(n);block_size=min(block_size,n);for(int i=1;i<=n;i++)scanf("%d",&num[i]);if(spj()){return 0;}ANS+=calc_small();ANS+=calc_large();cout<<ANS<<endl;return 0;}
/**************************************************************Problem: 3456User: zzzc18Language: C++Result: AcceptedTime:10868 msMemory:14540 kb****************************************************************/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 270000;typedef long long LL;class Fast_Number_Theory_Transform{private:const int MOD,G;int size,bit_length;int loc[MAXN];int A1[MAXN],B1[MAXN],tp[MAXN];template<typename type>int qpow(int x,type vvv){int mul=x;int re=1;LL k=vvv;for(LL i=1;i<=k;i<<=1){if(i&k)re=(LL)re*mul%MOD;mul=(LL)mul*mul%MOD;}return re;}void DFT(int *A,int *re,int len){init(len);for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;int Wn=qpow(G,(MOD-1)/k);for(int i=0;i<size;i+=k){int W=1;for(int j=0;j<len;j++){int u=re[i+j],v=(LL)re[i+j+len]*W%MOD;re[i+j]=(u+v)%MOD;re[i+j+len]=(u-v+MOD)%MOD;W=(LL)W*Wn%MOD;}}}}void IDFT(int *A,int *re,int len){init(len);for(int i=0;i<size;i++)re[i]=A[loc[i]];for(int k=2;k<=size;k<<=1){int len=k>>1;int Wn=inv(qpow(G,(MOD-1)/k));for(int i=0;i<size;i+=k){int W=1;for(int j=0;j<len;j++){int u=re[i+j],v=(LL)re[i+j+len]*W%MOD;re[i+j]=(u+v)%MOD;re[i+j+len]=(u-v+MOD)%MOD;W=(LL)W*Wn%MOD;}}}int tmp=inv(size);for(int i=0;i<size;i++)re[i]=(LL)re[i]*tmp%MOD;}int Inv(int degree,int *A,int *B){if(degree==1){B[0]=inv(A[0]);return degree;}int val=Inv((degree+1)>>1,A,B);memset(tp,0,sizeof(tp));for(int i=0;i<degree;i++)tp[i]=A[i];DFT(tp,A1,degree<<1);fill(B+val,B+size,0);DFT(B,B1,degree<<1);for(int i=0;i<size;i++)B1[i]=(LL)B1[i]*(2LL-(LL)B1[i]*A1[i]%MOD+MOD)%MOD;IDFT(B1,B,degree<<1);return degree;}public:Fast_Number_Theory_Transform(int _x,int _y):MOD(_x),G(_y){}int length(){return size;}inline int inv(int x){return qpow(x,MOD-2);}void Transform(int *A,int *B,int *ans,int len){DFT(A,A1,len);DFT(B,B1,len);for(int i=0;i<size;i++)A1[i]=(LL)A1[i]*B1[i]%MOD;IDFT(A1,ans,len);}void init(int x){for(size=1,bit_length=-1;size<x;size<<=1,bit_length++);int now=0;for(int i=0;i<size;i++){loc[i]=now;for(int j=1<<bit_length;(now^=j)<j;j>>=1);}}void Inv(int *A,int *B,int len){Inv(len,A,B);}int calc(int i){return qpow(2,(LL)i*(i-1)/2);}}NTT((479<<21)+1,3);int a[MAXN],b[MAXN];int ans[MAXN];int n;int fac[MAXN],inv_fac[MAXN];int F[MAXN],G[MAXN],C[MAXN];int inv_G[MAXN];void solve(){int MOD=(479<<21)+1;fac[0]=1;for(int i=1;i<=n;i++)fac[i]=(LL)fac[i-1]*i%MOD;inv_fac[n]=NTT.inv(fac[n]);for(int i=n-1;i>=0;i--)inv_fac[i]=(LL)inv_fac[i+1]*(i+1)%MOD;G[0]=1;for(int i=1;i<=n;i++){int tmp=NTT.calc(i);G[i]=(LL)tmp*inv_fac[i]%MOD;C[i]=(LL)tmp*inv_fac[i-1]%MOD;}NTT.Inv(G,inv_G,n+1);fill(G+n+1,G+NTT.length(),0);//NTT.Transform(G,inv_G,F);//printf("%d\n",F[0]);NTT.Transform(C,inv_G,F,n*2+1);printf("%d\n",(LL)F[n]*NTT.inv(inv_fac[n-1])%MOD);}int main(){//freopen("in.in","r",stdin);scanf("%d",&n);solve();return 0;}