码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4891: [Tjoi2017]龙舟

时间:2017-05-05 17:13:50      阅读:383      评论:0      收藏:0      [点我收藏+]

标签:else   bool   style   har   部分   bsp   turn   algorithm   void   

求$\frac{b_1b_2b_3...b_m}{a_1a_2a_3...a_m}\%M$

M<=1e18,m<=100000,数据组数<=50

用pollard-rho分解M的质因数,提取出$b_i,a_i$与M不互质的部分处理一下

#include<cstdio>
#include<algorithm>
typedef long long i64;
typedef long double ld;
char buf[65536],*ptr=buf+65536;
int G(){
    if(buf+65536==ptr)fread(ptr=buf,1,65536,stdin);
    return *ptr++;
}
i64 _(){
    i64 x=0;
    if(ptr-buf<65000){
        while(*ptr<48)++ptr;
        while(*ptr>47)x=x*10+(*ptr++)-48;
    }else{
        int c=G();
        while(c<48)c=G();
        while(c>47)x=x*10+c-48,c=G();
    }
    return x;
}
int n,m,k;
i64 b[100007],a[22][100007];
int fp,ts[100];
i64 fs[100];
i64 mul(i64 a,i64 b,i64 c){
    if(c<=2000000000ll)return a*b%c;
    i64 r=a*b-i64(ld(a)/c*b)*c;
    if(r>=c||r<=-c)r%=c;
    return r>=0?r:r+c;
}
i64 pw(i64 a,i64 n,i64 P){
    i64 v=1;
    for(;n;n>>=1,a=mul(a,a,P))if(n&1)v=mul(v,a,P);
    return v;
}
i64 gcd(i64 a,i64 b){
    if(a<0)a=-a;
    for(i64 c;b;c=a,a=b,b=c%b);
    return a;
}
bool mr(i64 n){
    i64 z=n-1;
    int t=0;
    while(~z&1)z>>=1,++t;
    for(int i=0;i<15;++i){
        i64 a=rand()%(n-1)+1;
        i64 x=pw(a,z,n);
        for(int j=0;j<t;++j){
            i64 y=mul(x,x,n);
            if(y==1&&x!=1&&x!=n-1)return 0;
            x=y;
        }
        if(x!=1)return 0;
    }
    return 1;
}
i64 get(i64 x,int c){
    int i=1,j=2;
    i64 a=(rand()^i64(rand())<<31)%(x-1)+1,b=a;
    while(1){
        a=mul(a,a,x);
        if((a+=c)>=x)a%=x;
        i64 p=gcd(a-b,x);
        if(p!=1)return p;
        if((++i)==j)j<<=1,b=a;
    }
}
void calc(i64 n){
    if(n==1)return;
    if(mr(n)){
        fs[fp++]=n;
        return;
    }
    for(int c=12347;;++c){
        i64 a=get(n,c);
        if(a!=n){
            i64 b=gcd(a,n/a);
            calc(a/b);
            calc(n/a/b);
            calc(b);
            return;
        }
    }
}
i64 cal(i64*b,i64*a,i64 M){
    fp=0;
    calc(M);
    std::sort(fs,fs+fp);
    fp=std::unique(fs,fs+fp)-fs;
    i64 phi_M=M;
    for(int i=0;i<fp;++i)ts[i]=0,phi_M=phi_M/fs[i]*(fs[i]-1);
    i64 B=1,A=1,x;
    for(int i=1;i<=m;++i){
        x=b[i];
        if(fs[0]==2)for(;~x&1;x>>=1,++ts[0]);
        for(int j=(fs[0]==2);j<fp;++j){
            for(i64 p=fs[j],y=x/p;y*p==x;x=y,y=y/p,++ts[j]);
        }
        B=mul(B,x,M);
    }
    for(int i=1;i<=m;++i){
        x=a[i];
        if(fs[0]==2)for(;~x&1;x>>=1,--ts[0]);
        for(int j=(fs[0]==2);j<fp;++j){
            for(i64 p=fs[j],y=x/p;y*p==x;x=y,y=y/p,--ts[j]);
        }
        A=mul(A,x,M);
    }
    B=mul(B,pw(A,phi_M-1,M),M);
    for(int i=0;i<fp;++i){
        if(ts[i]<0)return -1;
        B=mul(B,pw(fs[i],ts[i],M),M);
    }
    return B;
}
int main(){
    srand(77151);
    n=_();m=_();k=_();
    for(int i=1;i<=m;++i)b[i]=_();
    for(int t=1;t<=n;++t)
    for(int i=1;i<=m;++i)a[t][i]=_();
    for(int i=0;i<k;++i){
        int x=_();
        i64 M=_();
        printf("%lld\n",cal(b,a[x],M));
    }
    return 0;
}

 

bzoj4891: [Tjoi2017]龙舟

标签:else   bool   style   har   部分   bsp   turn   algorithm   void   

原文地址:http://www.cnblogs.com/ccz181078/p/6813574.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!