工程校赛 G(欧拉函数+扩展欧几里得+快速乘法+快速幂)

来源:互联网 发布:八爪鱼淘宝采集器贴吧 编辑:程序博客网 时间:2024/06/03 00:47
#define _CRT_SECURE_NO_WARNINGS#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <map>using namespace std;char str[] = "abcdefghijklmnopqrstuvwxyz,.;:!?";char str2[110000];//欧拉函数的直接求法//欧拉函数其实就是表示为//f(x)=x*(1-1/p1)(1-1/p2)(1-1/p3).....(1-1/pn);//其中p是x的不重复的质因子//这样子的话求法就简单了,借鉴之前的一个数的质因子求法,并带入公式即可.long long getoula(long long x){    long long temp = x;    for (long long i = 2; i*i <= x; i++)    if (x%i == 0)    {        while (x%i == 0)x /= i;        temp = temp / i*(i - 1);    }    if (x>1)        temp = temp / x*(x - 1);    return temp;} //ed ≡ 1 (mod φ(n))求解这个式子可以转换一下//变成ed+φ(n)*x=1;,这样子的话就可以可以用扩展欧几里德求得答案  void exgcd(long long a, long long  b, long long  &x, long long  &y){    if (b == 0)    {        x = 1;        y = 0;        return;    }    exgcd(b, a%b, x, y);    long long t = x;    x = y;    y = t - a / b*y;}long long getd(long long x, long long y){    long long a, b;    exgcd(x, y, a, b);    return (a+y)%y;} long long quick_cf(long long x, long long y, long long mod){    long long ans = 0;    while (y)    {        if (y & 1)        {            ans += x;            if (ans >=mod)                ans -= mod;        }        x += x;        y >>= 1;        if (x >=mod) x -= mod;    }    return ans;} long long quick_mod(long long x, long long y, long long mod){    long long ans = 1;    while (y)    {                 if (y & 1) ans = quick_cf(ans, x, mod);        y >>= 1;        x = quick_cf(x, x, mod);    }    return ans;} int main(){    long long n, e, c;    int s[255];    for (int i = 0; i<32; i++)        s[str[i]] = i;    while (~scanf("%lld%lld%lld", &n, &e, &c))    {        long long ou = getoula(n);        long long d = getd(e, ou);        long long m = quick_mod(c, d, n);        m %= 32;        scanf("%s", str2);        for (int i = 0; str2[i]; i++)        {            int cur = s[str2[i]];            str2[i] = str[cur^m];        }        puts(str2);    }}

0 0
原创粉丝点击