uva11916 Emoogle Grid (BSGS)
https://uva.onlinejudge.org/external/119/p11916.pdf
令m表示不能染色的格子的最大行号
设>m行时可以染k种颜色的格子数有ck个,恰好有m行时可以染k种颜色的格子数有ckm个
分m行、m+1行、>m+1行讨论
如果是m行:k^ckm * (k-1)^(n*m-b-ckm) = r
如果是m+1行, k^ckm * (k-1)^(n*m-b-ckm) * k^(ck-ckm) * (k-1)^(n-(ck-ckm)) = r
如果>m行,k^ckm * (k-1)^(n*m-b-ckm) * k^(ck-ckm) * (k-1)^(n-(ck-ckm)) * k^n^mm = r ,ans=m+1+mm
求mm用bsgs
注意:
1、后面注意b=0的情况,当b=0时,n*m-b-ckm 是负数,快速幂死循环,注意特判
2、用bsgs时,A^B≡C mod P,其中A=k^n,不能令A=k,求出的B再除以n
#include<map> #include<cmath> #include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int mod=1e8+7; #define N 501 struct node { int x,y; }e[N+1]; map<int,int>mp; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } int Pow(int a,long long b) { int res=1; for(;b;b>>=1,a=1LL*a*a%mod) if(b&1) res=1LL*res*a%mod; return res; } int get_inv(int a) { return Pow(a,mod-2); } int BSGS(int a,int b,int p) { mp.clear(); int m=sqrt(p); mp[b]=0; for(int i=1;i<=m;++i) { b=1LL*b*a%mod; mp[b]=i; } int am=Pow(a,m); int mul=1; for(int i=1;i<=m;++i) { mul=1LL*mul*am%mod; if(mp.find(mul)!=mp.end()) return i*m-mp[mul]; } return -1; } bool cmp(node p,node q) { if(p.y!=q.y) return p.y<q.y; return p.x<q.x; } int main() { int T; int n,k,b,r; int m,x,y; int ck,ckm; int a,rr; int ans; read(T); for(int t=1;t<=T;++t) { read(n); read(k); read(b); read(r); ck=ckm=n; m=0; for(int i=1;i<=b;++i) { read(e[i].x); read(e[i].y); if(e[i].x==1) ck--,ckm--; m=max(m,e[i].x); } sort(e+1,e+b+1,cmp); e[b+1].x=e[b+1].y=-1; for(int i=1;i<=b;++i) if(!(e[i].y==e[i+1].y && e[i].x==e[i+1].x-1)) { ck++; if(e[i].x!=m) ckm++; } if(m) { rr=1LL*Pow(k,ckm)*Pow(k-1,1LL*n*m-b-ckm)%mod; if(rr==r) { printf("Case %d: %d\n",t,m); continue; } rr=1LL*rr*Pow(k,ck-ckm)%mod; rr=1LL*rr*Pow(k-1,n-(ck-ckm))%mod; } else rr=Pow(k,n); if(rr==r) { printf("Case %d: %d\n",t,m+1); continue; } r=1LL*r*get_inv(rr)%mod; a=BSGS(Pow(k-1,n),r,mod); printf("Case %d: %d\n",t,a+m+1); } return 0; }