#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);
}
}
工程校赛 G(欧拉函数+扩展欧几里得+快速乘法+快速幂)
最新推荐文章于 2022-03-17 18:19:33 发布