Description
你的面前有N个数排成一行。分别为A1, A2, … , An。你打算在每相邻的两个 Ai和 Ai+1 间都插入一个加号或者
减号或者乘号。那么一共有 3^(n-1) 种可能的表达式。你对所有可能的表达式的值的和非常感兴趣。但这毕竟太
简单了,所以你还打算支持一个修改操作,可以修改某个Ai 的值。你能够编写一个程序对每个修改都输出修改完
之后所有可能表达式的和吗?注意,修改是永久的,也就是说每次修改都是在上一次修改的基础上进行, 而不是
在最初的表达式上进行。
Input
第一行包含 2 个正整数 N 和 Q,为数的个数和询问的个数。
接下来一行 n 个非负整数,依次表示a1,a2...an
在接下来 Q 行,其中第 ?? 行两个非负整数Ti 和Vi,表示要将 A
ti 修改为 Vi。其中 1 ≤ Ti ≤ N。
保证对于 1 ≤ J ≤ N, 1 ≤ i≤ Q,都有 Aj,Vi ≤ 10^4。
N,Q<=100000,本题仅有三组数据
Output
输出共 Q 行,其中第 i 行表示第 i 个询问之后所有可能表达式的和,对10^9 + 7 取模。
Sample Input
5 5
9384 887 2778 6916 7794
2 8336
5 493
3 1422
1 28
4 60
9384 887 2778 6916 7794
2 8336
5 493
3 1422
1 28
4 60
Sample Output
890543652
252923708
942282590
228728040
608998099
252923708
942282590
228728040
608998099
Solution
题意是求G^sum(C(n,k)),由于999911659是质数,可将sum(C(n,k))模phi(999911659)
999911659=2*3*4679*35617,直接lucas定理处理,然后用中国剩余定理即可
最后注意有个坑,就是G为999911659,输出0
999911659=2*3*4679*35617,直接lucas定理处理,然后用中国剩余定理即可
最后注意有个坑,就是G为999911659,输出0
#include<bits/stdc++.h>
typedef unsigned char uchar;
typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
#define xx first
#define yy second
template<typename T> inline T max(T a,T b){return a>b?a:b;}
template<typename T> inline T min(T a,T b){return a<b?a:b;}
template<typename T> inline T abs(T a){return a>0?a:-a;}
template<typename T> inline void repr(T &a,T b){if(a<b)a=b;}
template<typename T> inline void repl(T &a,T b){if(a>b)a=b;}
#define mp(a,b) std::make_pair(a,b)
#define pb push_back
const int mod[4]={2,3,4679,35617},rmod=999911659;
int cc[4][36000],ny[4][36000],mny[4];
void exgcd(int a,int b,int &x,int &y)
{
if(!b)
x=1,y=0;
else
{
exgcd(b,a%b,y,x);
y-=(a/b)*x;
}
}
inline int c(int n,int k,int m)
{
if(n<k)return 0;
return (ll)cc[m][n]*ny[m][k]*ny[m][n-k]%mod[m];
}
int lucas(int n,int k,int m)
{
if(n<k||k<0)return 0;
if(n<mod[m]&&k<mod[m])return c(n,k,m);
return lucas(n/mod[m],k/mod[m],m)*c(n%mod[m],k%mod[m],m)%mod[m];
}
#define pmax 40000
int prime[10000],pm;
bool np[pmax+1];
inline void initprime()
{
for(int i=2;i<=pmax;i++)
{
if(!np[i])prime[pm++]=i;
for(int j=0;j<pm&&i*prime[j]<=pmax;j++)
{
np[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
int ys[30][2],yc,rn,cf=0;
inline void judge(int x)
{
int s[4];
for(int i=0;i<4;i++)
s[i]=lucas(rn,x,i);
ll ans=0;
for(int i=0;i<4;i++)
ans+=(ll)(rmod-1)/mod[i]*mny[i]*s[i];
cf=(ans+cf)%(rmod-1);
}
void dfs(int x,int yi)
{
if(yi==yc)
judge(x);
else
for(int i=0,y=x;i<=ys[yi][1];i++,y*=ys[yi][0])
dfs(y,yi+1);
}
int main()
{
initprime();
int tmp;
for(int i=0;i<4;i++)
exgcd(mod[i],(rmod-1)/mod[i]%mod[i],tmp,mny[i]);
for(int i=0;i<4;i++)
{
cc[i][0]=ny[i][0]=1;
for(int j=1;j<mod[i];j++)
{
cc[i][j]=(ll)cc[i][j-1]*j%mod[i];
exgcd(mod[i],cc[i][j],tmp,ny[i][j]);
}
}
int n,g;
scanf("%d%d",&rn,&g);
if(g==rmod)
{
puts("0");
return 0;
}
n=rn;
for(int i=0;i<pm;i++)
{
if(n%prime[i]==0)
{
ys[yc][0]=prime[i];
while(n%prime[i]==0)n/=prime[i],ys[yc][1]++;
yc++;
}
}
if(n>1)ys[yc][0]=n,ys[yc][1]=1,yc++;
dfs(1,0);
if(cf<0)cf+=rmod-1;
ll ans=1;
for(ll u=g,i=1;i<=cf;i<<=1)
{
if(cf&i)ans=ans*u%rmod;
u=u*u%rmod;
}
printf("%lld\n",ans);
}