UVA 11916 Emoogle Grid 数论

来源:互联网 发布:天刀明月心捏脸数据女 编辑:程序博客网 时间:2024/06/05 16:23
#include <iostream>#include <algorithm>#include <math.h>#include <set>#include <map>using namespace std;#define LL long long#define maxn 505const LL mod=100000007;LL n,m,k,b,r,x[505],y[505];set<pair<LL,LL> >mm;void gcd(LL a,LL b,LL &d,LL &x,LL &y)//拓展欧几里得定理,求ax+by=gcd(a,b)的一组解{    if(!b){d=a;x=1;y=0;}    else{gcd(b,a%b,d,y,x);y-=x*(a/b);}}LL inv(LL a,LL n)//求得a在模n条件下的逆{   LL d,x,y;   gcd(a,n,d,x,y);   return d==1?(x+n)%n:-1;}LL pows(LL a,LL b)//快速幂求a^b{    LL s=1;    while(b)    {        if(b&1)            s=(s*a)%mod;        a=(a*a)%mod;        b=b>>1;    }    return s;}//求解模方程a^x=b(mod n)。n为素数,无解返回-1LL log_mod (LL a,LL b,LL n){    LL m,v,e=1,i;    m=(LL)sqrt(n+0.5);    v=inv(pows(a,m),n);    map<int,int>x;    x[1]=0;    for(i=1;i<m;i++)    {        e=(e*a)%n;        if(!x.count(e))x[e]=i;    }    for(i=0;i<m;i++)    {        if(x.count(b))return i*m+x[b];        b=(b*v)%n;    }    return -1;}LL fun(){    LL i,j,cnt,num=0;    for(i=0;i<b;i++)        if(x[i]!=m&&!mm.count(make_pair(x[i]+1,y[i])))num++;    num+=n;    for(i=0;i<b;i++)        if(x[i]==1)num--;    cnt=(pows(k,num)*pows(k-1,n*m-b-num))%mod;    if(cnt==r)return m;    num=0;    for(i=0;i<b;i++)        if(x[i]==m)num++;    cnt=(cnt*pows(k,num))%mod;    cnt=(cnt*pows(k-1,n-num))%mod;    m++;    return log_mod(pows(k-1,n),(r*inv(cnt,mod))%mod,mod)+m;}int main(){    LL T,tt=0;    cin>>T;    while(T--)    {        LL i,j;        cin>>n>>k>>b>>r;        mm.clear();        m=1;        for(i=0;i<b;i++)        {            cin>>x[i]>>y[i];            if(x[i]>m)m=x[i];            mm.insert(make_pair(x[i],y[i]));        }        cout<<"Case "<<++tt<<": "<<fun()<<endl;    }    return 0;}/*    求一个数的逆的意义:假定有两个整数a和b,其中a/b使整数,且a和b除以mod的余数是aa,bb,则a/b除以mod的余数等于(aa*bb^(-1))%mod。    本题中,cnt表示含有不能涂色格子的部分加上新增的一行的可涂方案,之后每加一行,那方案数就要乘以pow(k-1,n),从而可知最终方案数M=cnt*(k-1)^(n*t),M%mod=r.inv()为求逆函数。则(k-1)^(n*t)%mod=M/cnt=(r*inv(cnt))%mod    在解模方程a^x=b(mod)就可以求得t,其中(a=(k-1)^n,b=(r*inv(cnt)%mod))    对于含有不能涂色格子的部分,第一行和在它之上是不能涂色格子的格子有k种涂法,其余(k-1)种*/