2018CCPC-K - Mr. Panda and Kakin(欧拉定理&快速乘&CRT&EXGCD)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018CCPC-K - Mr. Panda and Kakin(欧拉定理&快速乘&CRT&EXGCD)相关的知识,希望对你有一定的参考价值。
2018CCPC-K - Mr. Panda and Kakin(欧拉定理&快速乘&CRT&EXGCD)
a b ( m o d n ) = c a^b\\pmod{n}=c ab(modn)=c
已知 n = p q , c , b = 2 30 + 3 n=pq,c,b=2^{30}+3 n=pq,c,b=230+3
利用RSA解密,找到 n \\sqrt{n} n附近的 p , q p,q p,q。
利用欧拉定理可得: a b ( m o d n ) = a b ( m o d φ ( n ) ) ( m o d n ) = a b ( m o d ( p − 1 ) ( q − 1 ) ) ( m o d n ) a^b\\pmod{n}=a^{b\\pmod{\\varphi(n)}}\\pmod{n}=a^{b\\pmod{(p-1)(q-1)}}\\pmod{n} ab(modn)=ab(modφ(n))(modn)=ab(mod(p−1)(q−1))(modn)
c = a b ( m o d φ ( n ) ) ( m o d n ) c=a^{b\\pmod{\\varphi(n)}}\\pmod{n} c=ab(modφ(n))(modn)
两边同时乘 b b b在 φ ( n ) \\varphi(n) φ(n)下的逆元,则 c b − 1 = a ( m o d n ) c^{b^{-1}}=a\\pmod{n} cb−1=a(modn)
则 a = c b − 1 ( m o d n ) a=c^{b^{-1}}\\pmod{n} a=cb−1(modn)
因为 b − 1 b^{-1} b−1可用 e x g c d exgcd exgcd求解。
因为 c c c很大,考虑用快速乘,注意这里不能用龟速乘,龟速乘会 T T T掉。
快速乘就是转化为 L D LD LD乘法,然后差自然溢出再取模。
code
// Problem: K - Mr. Panda and Kakin
// Contest: Virtual Judge - 2018 ccpc final [Cloned]
// URL: https://vjudge.net/contest/445564#problem/K
// Memory Limit: 262 MB
// Time Limit: 2000 ms
// Date: 2021-07-05 19:37:05
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
int t;
ll n,c;
typedef long double LD;
void exgcd(ll a,ll b,ll &x,ll &y){
if(!b) x=1,y=0;
else {
exgcd(b,a%b,y,x);
y-=a/b*x;
}
}
ll qmul1(ll a,ll b,ll p){ //快速乘
ll x=LD(a)/p*b;
return ((a*b-x*p)%p+p)%p;
}
ll ksm(ll a,ll n,ll mod){
ll s=1;
while(n){
if(n&1) s=qmul1(s,a,mod);
a=qmul1(a,a,mod);
n>>=1;
}
return s;
}
int main(){
scanf("%d",&t);
int kase=0;
while(t--){
scanf("%lld%lld",&n,&c);
ll p,q;
for(ll i=(ll)sqrt(n);i;i--)
if(n%i==0){
p=i,q=n/i;break;
}
ll d=(p-1)*(q-1);
ll a=(1LL<<30)+3,x,y;
exgcd(a,d,x,y);
x=(x%d+d)%d;
printf("Case %d: %lld\\n",++kase,ksm(c,x,n));
}
return 0;
}
方法2:中国剩余定理 C R T CRT CRT求解 a = c b − 1 ( m o d n ) a=c^{b^{-1}}\\pmod{n} a=cb−1(modn)
#include<bits/stdc++.h>
using namespace std;
#define int long long
int exgcd(int a,int b,int &x,int &y){ //扩展欧几里得
if(a==0&&b==0) return -1;
if(b==0){
x=1;y=0;
return a;
}
int gcd=exgcd(b,a%b,y,x);
y-=a/b*x;
return gcd;
}
int solve(int a,int b,int c){ //求逆元
int x,y;
int gcd=exgcd(a,b,x,y);
if(c%gcd!=0) return -1;
return (x%b+b)%b;
}
int fpow(int a,int b,int mod){ //快速幂
int ans=1;a%=mod;
while(b){
if(b&1) (ans*=a)%=mod;
(a*=a)%=mod;
b>>=1;
}
return ans;
}
int fmul(int a,int b,int mod){ //快速乘
int ans=0;a%=mod;
while(b){
if(b&1) ans=(ans+a)%mod;
a=(a+a)%mod;
b>>=1;
}
return ans;
}
int crt(int ai[], int mi[], int len) { //中国剩余定理
int ans = 0, lcm = 1;
for (int i = 0; i < len; i++) lcm *= mi[i];
for (int i = 0; i < len; i++) {
int Mi = lcm / mi[i];
int inv = fpow(Mi, mi[i] - 2, mi[i]);
int x = fmul(fmul(inv, Mi, lcm), ai[i], lcm); //若lcm大于1e9需要用快速乘fmul
ans = (ans + x) % lcm;
}
return ans;
}
int mi[5],ai[5];
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
int T,ca=0;cin>>T;
while(T--){
cout<<"Case "<<++ca<<": ";
int n,c,p,q;cin>>n>>c;
for(int i=sqrt(n);i>=0;i--) if(n%i==0){
p=i;q=n/i;
break;
}
int d=solve((1LL<<30)+3,(p-1)*(q-1),1);
if(d==-1){
cout<<"-1"<<endl;
continue;
}
ai[0]=fpow(c,d,p);ai[1]=fpow(c,d,q);
mi[0]=p;mi[1]=q;
cout<<crt(ai,mi,2)<<endl;
}
return 0;
}
貌似常数较大,复杂度没有上面的方法优秀。
以上是关于2018CCPC-K - Mr. Panda and Kakin(欧拉定理&快速乘&CRT&EXGCD)的主要内容,如果未能解决你的问题,请参考以下文章
Gym 101194F Mr. Panda and Fantastic Beasts
hdu6007 Mr. Panda and Crystal 最短路+完全背包
Mr. Panda and Crystal HDU - 6007 最短路+完全背包
[acm/icpc2016ChinaFinal][CodeforcesGym101194] Mr. Panda and Fantastic Beasts
费用流 ICPC 2016 China Final J. Mr.Panda and TubeMaster
Gym 101194C / UVALive 7899 - Mr. Panda and Strips - [set][2016 EC-Final Problem C]