您的位置:首页 > 其它

【GDOI三校联考】Pow

2016-03-21 18:57 218 查看

Description

给出t组询问,每组询问给出n个数,a1~an,和模数p,求a1^a2^….an mod p的值。

t<=100,ai,p<10^7,n<=20

Solution

这样我们只需要快速计算axmodp的值就可以了。

如果gcd(a,p)=1的话,那么aφ(p)≡1modp

所以ax≡axmodφ(p)modp

用快速幂计算就好了。

如果不互质呢?

设g=gcd(a,p),a′=a/g,p′=b/g,ans为答案,则

gx∗a′x≡ansmodp′∗g

同时除以g

gx−1∗a′x≡ansgmodp′

这时候gcd(a′,p′)=1就可以用最上面的方法求出来了。

然后?就没有然后了。

注意,因为有模,x可以等于0,这时gx−1要用逆元。

这次真的没有了。

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define ll long long
#define N 10000000
using namespace std;
ll n,p,x,ty,b[25],phi[N+5];
int bz[N+5],pr
,tot;
ll mi(ll x,ll y,ll p) {
ll z;
for(z=1;y;y / =2) {
if (y%2) z=z*x%p;
x=x*x%p;
}
return z;
}
int gcd(int x,int y) {
return (y)?gcd(y,x%y):x;
}
ll pow(ll x,ll y) {
if (x>n) return 1;
ll g=gcd(b[x],y);y/=g;b[x]/=g;
ll t=pow(x+1,phi[y]),ans;
if (t) ans=mi(g,t-1,y)*mi(b[x],t,y)%y;
else ans=mi(g,phi[y]-1,y)*mi(b[x],t,y)%y;
return ans*g;
}
int main() {
phi[1]=1;
fo(i,2,N) {
if (!bz[i]) pr[++tot]=i,phi[i]=i-1;
fo(j,1,tot) {
int k=i*pr[j];if (k>N) break;bz[k]=1;
if (!(i%pr[j])) {
phi[k]=phi[i]*pr[j];break;
}
phi[k]=phi[i]*(pr[j]-1);
}
}
for(scanf("%lld",&ty);ty;ty--) {
scanf("%lld%lld",&n,&p);
fo(i,1,n) scanf("%lld",&b[i]);
printf("%lld\n",pow(1,p));
}
}


(为什么每次/号都会带出一片绿色?(>_<)强迫症表示不爽~)

另,其实这是水法,为什么g−1一定存在!!!

@WerKeyTom_FTD

又另,@能用吗?(我too young)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: