Remainder Calculator-指数循环结+欧拉函数

来源:互联网 发布:捷通人才系统源码 编辑:程序博客网 时间:2024/04/30 15:14

耗时好久,终于把这个题目给做出来了,不容易啊,弱校的数学始终是硬伤啊~~~

公式:

a^b=a^(b%phi(c)+phi(c))(mod c);

phi(c)为1~c中,与c互质的数的个数。

((a^b)^c)=a^(b^c)

a^(b^c)=a^(b^c%phi(c)+phi(c)) (mod c);

b^c%phi(c)=b^(c%phi(phi(c))+phi(phi(c)));

#include<stdio.h>#include<iostream>#include<string.h>#include<algorithm>#include<queue>#include<stack>#include<map>#include<string>#include<stdlib.h>#define INF_MAX 0x7fffffff#define INF 999999#define max3(a,b,c) (max(a,b)>c?max(a,b):c)#define min3(a,b,c) (min(a,b)<c?min(a,b):c)#define mem(a,b) memset(a,b,sizeof(a))using namespace std;struct node{    int u;    int v;    int w;    bool friend operator < (node a, node b){        return a.w < b.w;    }}edge[1001];int gcd(int n,int m){if(n<m) swap(n,m);return n%m==0?m:gcd(m,n%m);}int lcm(int n,int m){if(n<m) swap(n,m);return n/gcd(n,m)*m;}int a[10001];int b[10001];int p[10001];int phi(int x){    int m;    m=x;    int i;    for(i=2;i*i<=x;i++)    {        if(x%i==0)        {            m=m-m/i;            while(x%i==0)x=x/i;        }    }    if(x>1)    m=m-m/x;    return m;}int ex(int a,int b,int p){    if(b==0)return 1%p;    if(b==1)return a%p;    int tx;    tx=ex(a,b/2,p);    tx=tx*tx%p;    if(b%2==1)tx=tx*a%p;    return tx;}int main(){    int T,i,j;    int m,n;    cin>>T;    while(T--)    {        cin>>n>>m;        for(i=0;i<n;i++)        {            cin>>a[i];        }        if(a[0]>=m)        {            puts("0");            continue;        }        p[0]=m;        for(i=1;i<n;i++)        {            p[i]=phi(p[i-1]);        }        for(i=n-1;i>=1;i--)        {            if(a[i]>=p[i])b[i]=p[i];            else            {                int as=1;                for(j=2;j<=a[i];j++)                {                    as*=j;                    as=as%p[i];                }                if(i==n-1)                {                    b[i]=as+p[i];                }                else                {                    b[i]=ex(as,b[i+1],p[i])+p[i];                }            }        }        int as;        as=1;        for(i=2;i<=a[0];i++)        {            as*=i;            as=as%m;        }        cout<<ex(as,b[1],m)<<endl;    }    return 0;}