题意:
在一个M*N的矩阵内涂K种颜色。
其中有B个格子不能涂色,并且每个单元格不能和上面的那个单元格颜色一样。
已知N和总共的结果R,求最少满足的行M。
数据都对100,000,007.取模。
思路:
由于输入的不能涂色的点的X坐标一定在M以内。所以就记录一下maxX
把整个矩阵分成3个部分。
第一个部分是maxX*N.这部分的答案可以算出来看是否满足。
第二个部分是(maxX+1)*N.这个部分都是多了一行,为了去掉有些格子不能填带来的影响。
第三个部分就是M*N了,后面的(M-maxX-1)行每个格子填的颜色都是只有K-1种。
这时候设前面的答案为ans,设M-maxX-1=T
则 ans*(K-1)^(T*N) = R (mod 100000007)
这时候其实就需要求一个 A^X=B (mod M) 时的X
需要用一个枚举的方法。
代码:
#include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"queue" #include"algorithm" #include"iostream" #include"map" #define ll long long using namespace std; int mark[502][502]; map<int,int>id; ll mod=100000007; int n,k,b,idcnt,maxx,maxcnt; ll r; ll power(ll a,ll b) { ll ans=1; while(b) { if(b&1) ans=(ans*a)%mod; a=(a*a)%mod; b/=2; } return ans%mod; } ll inv(ll x) { return power(x,mod-2); } ll log_mod(ll a,ll b) { ll m,v,e=1,i; m=(ll)sqrt(mod+0.5); v=inv(power(a,m)); map<ll,ll>x; x.clear(); x[1]=0; for(i=1;i<m;i++) { e=e*a; if(e>=mod) e%=mod; if(x[e]==0) x[e]=i; } for(i=0;i<m;i++) { if(x[b])return i*m+x[b]; b=b*v; if(b>=mod) b%=mod; } return -1; } int solve() { //1~maxx ll ans=1; if(maxx!=0) { for(int i=1;i<=idcnt;i++) { int cur=0; mark[i][++mark[i][0]]=maxx+1; for(int j=1;j<=mark[i][0];j++) { int sum=mark[i][j]-cur-1; cur=mark[i][j]; if(sum==0) continue; ans*=k; if(ans>=mod) ans%=mod; ans*=power(k-1,sum-1); if(ans>=mod) ans%=mod; } } ans*=power(k,n-idcnt); if(ans>=mod) ans%=mod; ans*=power(k-1,(maxx-1LL)*(n-idcnt)); if(ans>=mod) ans%=mod; if(ans==r) return maxx; } //maxx+1 ans*=power(k,maxcnt); if(ans>=mod) ans%=mod; ans*=power(k-1,n-maxcnt); if(ans>=mod) ans%=mod; if(ans==r) return maxx+1; ll tep=inv(ans); ll A,B; B=(tep*r)%mod; A=power(k-1,n); return log_mod(A,B)+maxx+1; } int main() { int t,cas=1; cin>>t; while(t--) { scanf("%d%d%d%lld",&n,&k,&b,&r); memset(mark,0,sizeof(mark)); id.clear(); idcnt=0; maxx=0; maxcnt=n; for(int i=0;i<b;i++) { int x,y; scanf("%d%d",&x,&y); if(id[y]==0) id[y]=++idcnt; mark[id[y]][++mark[id[y]][0]]=x; if(x>maxx) { maxx=x; maxcnt=1; } else if(x==maxx) maxcnt++; } printf("Case %d: %d\n",cas++,solve()); } return 0; }
原文:http://blog.csdn.net/wdcjdtc/article/details/44655663