CQOI2016 密钥破解 pollard-rho

鬼畜的大整数分割算法泼辣的肉,纯属人品优化,然而能跑的飞快。

反正很强的一个鬼东西 学习链接已经狗带了,不过网上大把

/* ***********************************************
Author        :BPM136
Created Time  :2016/4/24 20:41:18
File Name     :A.cpp
************************************************ */

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<bitset>
#include<queue>
#include<ctime>
#include<set>
#include<utility>
#include<vector>
#include<functional>
#include<numeric>
#include<memory>
#include<iterator>
#define LL long long
#define DB double
#define LB long double
#define UL unsigned long
#define ULL unsigned long long
#define pb push_back
#define popb pop_back
#define get(a,i) a&(1<<(i-1))
#define PAU putchar(32)
#define ENT putchar(10)
#define clr(a,b) memset(a,b,sizeof(a))
#define fo(_i,_a,_b) for(int _i=_a;_i<=_b;_i++)
#define fd(_i,_a,_b) for(int _i=_a;_i>=_b;_i--)
#define efo(_i,_a) for(int _i=last[_a];_i!=0;_i=e[_i].next)
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define filein(x) freopen(#x".in","r",stdin)
#define fileout(x) freopen(#x".out","w",stdout)
#define mkd(x) freopen(#x".in","w",stdout);
#define setlargestack(x) int size=x<<20;char *p=(char*)malloc(size)+size;__asm__("movl %0, %%esp\n" :: "r"(p));
#define end system("pause")
using namespace std;
LL read()
{
         LL f=1,d=0;char s=getchar();
         while (s<48||s>57){if (s==45) f=-1;s=getchar();}
         while (s>=48&&s<=57){d=d*10+s-48;s=getchar();}
         return f*d;
}
LL readln()
{
       LL f=1,d=0;char s=getchar();
       while (s<48||s>57){if (s==45) f=-1;s=getchar();}
       while (s>=48&&s<=57){d=d*10+s-48;s=getchar();}
       while (s!=10) s=getchar();
       return f*d;
}
inline void write(LL x)
{
    if(x==0){putchar(48);return;}if(x<0)putchar(45),x=-x;
    int len=0,buf[20];while(x)buf[len++]=x%10,x/=10;
    for(int i=len-1;i>=0;i--)putchar(buf[i]+48);return;
}
inline void writeln(LL x){write(x);ENT;}

const LL MODr = 1000000007LL;

LL e, N, c;
LL r, d, n;
LL p, q;

LL C = 2;

LL MUL(LL a, LL k, LL MOD) {
	LL ret = 0;
	while (k) {
		if(k & 1) ret = (ret + a) %MOD;
		a = (a + a) %MOD;
		k >>= 1;
	}
	return ret;
}

LL KSM(LL a, LL k, LL MOD) {
	LL ret = 1;
	while (k) {
		if(k & 1) ret = MUL(ret, a, MOD);
		a = MUL(a, a, MOD);
		k >>= 1;
	}
	return ret;
}

LL gcd(LL a, LL b) {
	return b == 0 ? a: gcd(b, a % b);
}

LL f(LL x) {
	LL ret = ( (LL) MUL(x, x, N) + C ) % N;
	return ret;
}

void PLrho(LL x) {
	p = f(1);
	q = f(p);
	while (1) {
		LL GCD = gcd( abs( p - q ), x);
		if(GCD > 1 || GCD == x) {
			p = GCD;
			q = x / p;
			return ;
		}
		p = f(p);
		q = f( f(q) );
		if( p == q ) {
			C = 1LL * ((rand() * rand() % N) * (rand() * rand() % N)) % N;
			while(p != q) {
				p = f(1);
				q = f(p);
			}
		}
	}
}

struct node {
	LL x, y;
};
node Exgcd(LL a, LL b) {
	if(b == 0) {
		node ret ;
		ret.x = 1;
		ret.y = 0;
		return ret;
	}
	node tmp = Exgcd(b, a % b);
	node ret;
	ret.x = tmp.y;
	ret.y = tmp.x - (a / b) * tmp.y;
	return ret;
}

int main() {
//	DB tt = clock();
//	file(A);
	e=read(), N=read(), c=read();
	PLrho(N);
//	cout<< clock() - tt <<endl;
	r = (p - 1) * (q - 1);
	node tmp = Exgcd(e, r);
	d = tmp.x; d = (d % r + r) %r;
	n = KSM(c, d, N);
	cout<< d << ' ' << n <<endl;
	return 0;
}


你可能感兴趣的:(数论,逆元,泼辣的肉)