题意:
在一个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