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

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

时间:2018-12-17 14:42:04      阅读:264      评论:0      收藏:0      [点我收藏+]

标签:std   i++   tmp   new   span   ring   fine   mes   sizeof   

#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\n",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\n", leftNum);
            }
        }else puts("NO");
    }
}

 

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

标签:std   i++   tmp   new   span   ring   fine   mes   sizeof   

原文地址:https://www.cnblogs.com/033000-/p/10130588.html

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