https://codeforces.com/contest/1314/problem/F
给出 \(a,b\) ,在nim积的意义下求一个小于 \(2^{64}\) 次方的数 \(x\) 满足
\(0 \le a,b < 2^{64}\)
在剩余系中求对数的方法,我们采用BSGS在 \(O(\sqrt m)\) 的时间求解.然而这无法直接套用在这道题上.
\(a\) 的乘法群的大小为 \(F=2^{64}-1\) .
观察发现 \(F=3 \times 5 \times 17 \times 257 \times 641 \times 65537 \times 6700417\) .其中每个数都是一个不大的质数.
所以考虑求出 \(x\) 对于每个上列质数的余数后用中国剩余定理合并.
加入我们要对于 \(p\) 求解,那么
其中 \(a^F=1\)
令 \(a‘ = a^{\frac Fp},b‘=b^{\frac Fp}\) 那么我们要求的就是
其中 \(y \in [0,p)\) ,所以可以用BSGS的思想求解.
#include <cmath>
#include <cstdio>
#include <cstring>
#include <vector>
#define inver_nim(a) power_nim(a,F-1)
#define inver(a,mod) power(a,mod-2,mod)
#define debug(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const ull F=~0ull;
static int p[]={3,5,17,257,641,65537,6700417};
int T;
ull a,b;
int x[7];
ull nim[256][256];
ull f(ull x,ull y,int len=32) {
if(x==0||y==0) return 0;
if(x==1||y==1) return x*y;
if(len<=4&&nim[x][y]) return nim[x][y];
ull xa=x>>len,xb=x^(xa<<len),ya=y>>len,yb=y^(ya<<len);
ull a=f(xb,yb,len>>1),b=f(xa^xb,ya^yb,len>>1),c=f(xa,ya,len>>1),d=f(c,1ull<<len-1,len>>1);
ull re=((b^a)<<len)^a^d;
if(len<=4) nim[x][y]=re;
// debug("%llu %llu %llu\n",x,y,re);
return re;
}
ull power_nim(ull x,ull y) {
ull re=1;
while(y) {
if(y&1) re=f(re,x);
x=f(x,x);
y>>=1;
}
return re;
}
ll power(ll x,ll y,int mod) {
ll re=1;
while(y) {
if(y&1) re=re*x%mod;
x=x*x%mod;
y>>=1;
}
return re;
}
ull add(ull x,ull y) {return x>=F-y?x+y-F:x+y;}
ull mul(ull x,ull y) {
ull re=0;
while(y) {
if(y&1) re=add(re,x);
x=add(x,x);
y>>=1;
}
return re;
}
namespace Hash {
const int mod=2e3+7;
int head[mod];
struct node {
int val,nex; ull key;
node(int val=0,int nex=0,ull key=0):val(val),nex(nex),key(key){}
};
vector<node> G;
int find(ull k) {
int z=k%mod;
for(int i=head[z];~i;i=G[i].nex) {
if(G[i].key==k) return G[i].val;
}
return -1;
}
void insert(int v,ull k) {
if(find(k)!=-1) return;
int z=k%mod;
G.push_back(node(v,head[z],k)),head[z]=G.size()-1;
}
void init() {
memset(head,-1,sizeof(head));
G.clear();
}
}
ull BSGS(ull a,ull b,int p,int &re) {
// debug("%llu %llu %d\n",a,b,p);
if(a==1&&b==1) {re=0; return 1;}
Hash::init();
int m=ceil(sqrt(p));
ull t1=1,t2=1;
for(int j=0;j<m;++j) {
// debug("%d %llu\n",j,t1);
Hash::insert(j,t1);
t1=f(t1,a);
}
t1=inver_nim(t1);
// debug("%lld\n",t1);
for(int i=0;i<m;++i) {
// debug("%d %llu\n",i,f(b,t2));
int j=Hash::find(f(b,t2));
if(j!=-1) {re=i*m+j; return 1;}
t2=f(t2,t1);
}
return 0;
}
int main() {
// freopen("CF.in","r",stdin);
// freopen("CF.out","w",stdout);
scanf("%d",&T);
while(T--) {
scanf("%llu%llu",&a,&b);
bool ok=1;
for(int i=0;i<7;++i) {
if(!BSGS(power_nim(a,F/p[i]),power_nim(b,F/p[i]),p[i],x[i])) {ok=0; break;}
// debug("%d %d\n",i,x[i]);
}
if(!ok) {puts("-1"); continue;}
ull an=0;
for(int i=0;i<7;++i) {
an=add(an,mul((ull)x[i]*inver(F/p[i]%p[i],p[i]),F/p[i]));
}
printf("%llu\n",an);
}
return 0;
}
CodeForces 1314F Bad Croptography
原文:https://www.cnblogs.com/ljzalc1022/p/13053323.html