poj3708 扩展中国剩余定理+大数转d进制

Posted 033000-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj3708 扩展中国剩余定理+大数转d进制相关的知识,希望对你有一定的参考价值。

#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define pf printf
#define sf scanf
const int maxn=1000+5;
int d,in1[maxn],in2[maxn],inm[maxn],ink[maxn],a[maxn],b[maxn];

void tran(int *ten,int len,int &newlen,int *res){
    newlen=0;
    int k=0;
    while(k<len){
        ten[len]=0;
        for(int i=k;i<len;i++){
            ten[i+1]+=(ten[i]%d)*10;
            ten[i]=ten[i]/d;
        }
        res[newlen++]=ten[len]/10;
        while(k<len&&ten[k]==0) ++k;
    }
    //for(int i=0;i<newlen;i++)
        //printf("%d",res[i]);
        //puts("");
}
int left[maxn],mod[maxn];
void GET_LOOP(int cnt){
    --cnt;
    memset(left,-1,sizeof(left));
    mod[cnt]=1;
    if(inm[cnt]==ink[cnt]) left[cnt]=0;
    int k=0;
    for(int i=a[inm[cnt]];i!=inm[cnt];i=a[i]){
        ++mod[cnt];
        ++k;
        if(i==ink[cnt]) left[cnt]=k;
    }
    for(int i=0;i<cnt;i++){
        mod[i]=1;
        k=0;
        if(inm[i]==ink[i]) left[i]=0;
        for(int j=b[inm[i]];j!=inm[i];j=b[j]){
            ++mod[i];
            ++k;
            if(j==ink[i]) left[i]=k;
        }
    }
    //for(int i=0;i<=cnt;i++)
        //pf("%d %d
",left[i],mod[i]);

}

ll exgcd(ll a,ll b,ll &x,ll &y){
    if(!b){x=1,y=0;return a;}
    ll re=exgcd(b,a%b,x,y),tmp=x;
    x=y,y=tmp-(a/b)*y;
    return re;
}

int main(){
    //freopen("in.txt","r",stdin);
    //if(test()) return 0;
    char num1[100+5],num2[100+5];
    int len1,len2;
    while(scanf("%d",&d)==1&&d!=-1){
        for(int i=1;i<d;i++) scanf("%d",&a[i]);
        for(int i=0;i<d;i++) scanf("%d",&b[i]);
        scanf("%s",num1);
        len1=strlen(num1);
        for(int i=0;i<len1;i++) in1[i]=num1[i]-0;
        scanf("%s",num2);
        len2=strlen(num2);
        for(int i=0;i<len2;i++) in2[i]=num2[i]-0;
        int cnt1,cnt2;
        tran(in1,len1,cnt1,inm);
        tran(in2,len2,cnt2,ink);
        if(cnt1==cnt2){
            GET_LOOP(cnt1);
            bool f = 0;
            for(int i = 0; i < cnt1; ++i) if(left[i] == -1) f = 1;
            if(f) puts("NO");
            else{
                ll modNum = mod[0] * 1ll, leftNum = left[0] * 1ll, x, y;
                for(int i = 1; i < cnt1; ++i){
                    ll c = left[i] * 1ll - leftNum;
                    ll m1 = modNum, m2 = mod[i] * 1ll;
                    ll d = exgcd(modNum, m2, x, y);
                    if(c % d){
                        f = 1;
                        break;
                    }
                    x *= c / d;
                    ll t = m2 / d;
                    x = (x % t + t) % t;
                    modNum *= t;
                    leftNum = (leftNum + x * m1) % modNum;
                }
                if(f)   puts("NO");
                else    printf("%lld
", leftNum);
            }
        }else puts("NO");
    }
}

 

以上是关于poj3708 扩展中国剩余定理+大数转d进制的主要内容,如果未能解决你的问题,请参考以下文章

POJ1006Biorhythms——中国剩余定理

Strange Way to Express Integers POJ 2891(中国剩余定理扩展)

POJ2891 Strange Way to Express Integers 扩展欧几里德 中国剩余定理

Biorhythms POJ 1006(中国剩余定理)

Biorhythms POJ - 1006 中国剩余定理

欧几里得(辗转相除gcd)扩欧(exgcd)中国剩余定理(crt)扩展中国剩余定理(excrt)简要介绍