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\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");
    }
}

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

时间: 2024-11-06 03:46:33

poj3708 扩展中国剩余定理+大数转d进制的相关文章

中国剩余定理(CRT) &amp; 扩展中国剩余定理(ExCRT)总结

中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结 标签:数学方法--数论 阅读体验:https://zybuluo.com/Junlier/note/1300035 前置浅讲 前置知识点:\(Exgcd\) 这两个东西都是用来解同余方程组的 形如 \[ \left\{ \begin{aligned} x\equiv B_1(mod\ W_1)\x\equiv B_2(mod\ W_2)\ \cdots\x\equiv B_n(mod\ W_n)\\end{aligned} \rig

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

1.欧几里得算法(辗转相除法) 直接上gcd和lcm代码. 1 int gcd(int x,int y){ 2 return y==0?x:gcd(y,x%y); 3 } 1 int lcm(int x,int y){ 2 return x*y/gcd(x,y); 3 } 2.扩欧:exgcd:对于a,b,一定存在整数对(x,y)使ax+by=gcd(a,b)=d ,且a,b互质时,d=1. x,y可递归地求得. 我懒得改返回值类型了 1 long long exgcd(long long a,

Acwing-204-表达整数的奇怪方式(扩展中国剩余定理)

链接: https://www.acwing.com/problem/content/206/ 题意: 给定2n个整数a1,a2,-,an和m1,m2,-,mn,求一个最小的非负整数x,满足?i∈[1,n],x≡mi(mod ai). 思路: 扩展中国剩余定理模板题. 代码: #include <bits/stdc++.h> using namespace std; typedef long long LL; LL R[50], M[50]; int n; LL ExGcd(LL a, LL

LUOGU P4777 【模板】扩展中国剩余定理(EXCRT)

传送门 解题思路 扩展 $crt?$,就是中国剩余定理在模数不互质的情况下,首先对于方程 ?     $\begin{cases} x\equiv a_1\mod m_1\\x\equiv a_2\mod m_2\end{cases}$ 来说,可以将其写为: $\begin{cases} x=k_1*m_1+a_1\\x=k_2*m_2+a_2\end{cases}$ 然后联立方程: ?     $k_1*m_1+a_1=k_2*m_2+a_2$ $\Leftrightarrow -k_1*m_

扩展中国剩余定理(扩展CRT)详解

今天在$xsy$上翻题翻到了一道扩展$CRT$的题,就顺便重温了下 中国剩余定理是用于求一个最小的$x$,满足$x\equiv c_i \pmod{m_i}$. 正常的$CRT$有一个微小的要求,就是$\forall i,j (m_i,m_j)=1$. 在某些情况下,这个式子无法被满足,这个时候就要用扩展$CRT$来求解了. 我们先假设我们只有两条方程要被求解,它们分别是: $\begin{cases} x\equiv c_1 \pmod{m_1}\\x\equiv c_2 \pmod{m_2}

Luogu 4777 【模板】扩展中国剩余定理(EXCRT)

复习模板. 两两合并同余方程 $x\equiv C_{1} \ (Mod\ P_{1})$ $x\equiv C_{2} \ (Mod\ P_{2})$ 把它写成不定方程的形式: $x = C_{1} + P_{1} * y_{1}$ $x = C_{2} + P_{2} * y_{2}$ 发现上下两式都等于$x$ 所以$C_{1} + P_{1} * y_{1} = C_{2} + P_{2} * y_{2}$ 稍微移项一下,有$P_{1} * y_{1} + P_{2} * (-y_{2})

【文文殿下】扩展中国剩余定理(板子)

bool CRT(int a1,int m1,int a2,int m2,int &a,int &m) { int x,y; int d = exgcd(m1,m2,x,y); int z = a2-a1; if(z%d) return 0; x = (int)(1LL*x*(z/d)%(m2/d)); m=int(1LL*m1*m2/d); a = int((1LL*a1+1LL*x*m1%m+m)%m); return 1; } 原文地址:https://www.cnblogs.com

P4777 【模板】扩展中国剩余定理(EXCRT)

题目描述 给定 nnn组非负整数 ai,bia_i, b_iai?,bi?,求解关于 xxx的方程组{x≡b1 (mod a1)x≡b2 (mod a2)...x≡bn (mod an)\begin{cases} x \equiv b_1\ ({\rm mod}\ a_1) \\ x\equiv b_2\ ({\rm mod}\ a_2) \\ ... \\ x \equiv b_n\ ({\rm mod}\ a_n)\end{cases}??????????x≡b1? (mod a1?)x≡b

扩展中国剩余定理 乱写

有k个形式类似于x≡a[i](mod m[i])的方程组,求一个满足条件的最小x或判断无解,不保证m[i]之间互质. 那么我一开始有一个疑问,我为什么要学excrt,不就是模数不互质了吗... crt用到了exgcd来求 m[i]不互质,原来crt的 原文地址:https://www.cnblogs.com/yxsplayxs/p/11143651.html