题解:P4777 【模板】扩展中国剩余定理(EXCRT)
题解:P4777 【模板】扩展中国剩余定理(EXCRT)
看到题目:同余方程组?中国剩余定理!
不过由于本题中的 aiaiai 并不是互质的,所以我们需要使用扩展中国剩余定理(EXCRT)。
假设同余方程组由以下两个同余方程组成
x≡b1mod a1x\equiv b1\mod a1x≡b1moda1
x≡b2mod a2x\equiv b2\mod a2x≡b2moda2
可以转化为不定方程
x=a1×p+b1x=a1\times p+b1x=a1×p+b1
x=a2×q+b2x=a2\times q+b2x=a2×q+b2
则
a1×p−a2×q=b2−b1a1\times p-a2\times q=b2-b1a1×p−a2×q=b2−b1
诶?好熟悉的式子,可以使用扩展欧几里得算法!
根据裴蜀定理可得,只有在 gcd(a1,a2)∣(b2−b1)\gcd(a1,a2)\mid (b2-b1)gcd(a1,a2)∣(b2−b1) 时才有解,当然题目已经保证了有解。
设 A=gcd(a1,a2)A=\gcd(a1,a2)A=gcd(a1,a2),根据扩展欧几里得可以求出 ppp 与 qqq 的一组解为 p1p1p1 与 q1q1q1,可求出通解为 X=p1+a2A×kX=p1+\frac{a2}{A}\times kX=p1+Aa2×k 与 Y=q1+a1A×kY=q1+\frac{a1}{A}\times kY=q1+Aa1×k。
因为题目要求最小非负整数解,所以 kkk 取 1,此时 x=a1×X+b1x=a1\times X+b1x=a1×X+b1,即 a1×(p1+a2A)+b1=a1×p1+a1×a2A+b1a1\times (p1+\frac{a2}{A})+b1=a1\times p1+\frac{a1\times a2}{A}+b1a1×(p1+Aa2)+b1=a1×p1+Aa1×a2+b1,其中 a1×a2A=lcm(a1,a2)\frac{a1\times a2}{A}=lcm(a1,a2)Aa1×a2=lcm(a1,a2)。
此时可以将原本两个同余方程等价合并为
x≡a1×p1+b1mod lcm(a1,a2)x\equiv a1\times p1+b1 \mod lcm(a1,a2)x≡a1×p1+b1modlcm(a1,a2)
所以 nnn 个同余方程合并 n−1n-1n−1 次就可以合并为一个方程,此时答案即为上式中的 a1×p1+b1a1\times p1+b1a1×p1+b1。
最终代码复杂度为 O(n log n)O(n\ log\ n)O(n log n)。
代码
typedef __int128 ll;
void exgcd(ll a,ll b,ll &d,ll &x,ll &y){//扩展欧几里得if(b==0){d=a;x=1;y=0;return ;} exgcd(b,a%b,d,y,x);y-=(a/b)*x;
}
void pr(ll x){if(x/10)pr(x/10);putchar('0'+x%10);
}
int main(){ios::sync_with_stdio(0);cin.tie(0);ll d,x,y,a1,b1,a2,b2;long long n,aa,bb,aaa,bbb;cin>>n>>aa>>bb;//第1个同余方程a1=aa;b1=bb;for(int i=2;i<=n;i++){cin>>aaa>>bbb;//第2~n个同余方程a2=aaa;b2=bbb;exgcd(a1,a2,d,x,y);ll dx=a2/d;//即为a2/A,因为d为gcd(a1,a2)if(dx<0)dx=-dx;//取绝对值x=x*((b2-b1)/d);//根据扩欧求一组解x=(x%dx+dx)%dx;//防止x为负b1=a1*x+b1;//记录答案a1=a1/d*a2;}pr(b1);return 0;
}