bzoj4891: [Tjoi2017]龙舟

Posted ccz181078

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4891: [Tjoi2017]龙舟相关的知识,希望对你有一定的参考价值。

求$\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]龙舟的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4888: [Tjoi2017]异或和 BIT-乱搞

bzoj4887:[Tjoi2017]可乐 矩阵乘法,快速幂

BZOJ 4888 [Tjoi2017]异或和

BZOJ_4892_[Tjoi2017]dna_哈希

bzoj4889: [Tjoi2017]不勤劳的图书管理员 分块-BIT

[BZOJ4890][TJOI2017]城市(DP)