您的位置:首页 > 其它

[uva11916] Emoogle Grid (离散对数)

2014-12-12 19:47 302 查看
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud

Emoogle Grid
You have to color an MxN ( 1

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <set>
#define X first
#define Y second
#include <map>
using namespace std;

typedef pair<int,int> PII;
typedef long long ll;
ll n,k,b,r;
set<PII> s;
PII p[1010];
ll maxx=0;
const int mod=100000007;
ll mul_mod(ll x,ll y)
{
return (ll)x*y%mod;
}
ll fast_mod(int m,ll t)
{
ll temp=(long long)m;
ll ret=1LL;
while(t)
{
if(t&1)ret=mul_mod(ret,temp);
temp=mul_mod(temp,temp);
t/=2;
}
return ret;
}
ll ext_gcd(ll a,ll t,ll &d,ll &x,ll &y)
{
if(!t){d=a;x=1;y=0;}
else {
ext_gcd(t,a%t,d,y,x);y-=x*(a/t);
}
}
ll inv(ll a)
{
ll d,x,y;
ext_gcd(a,mod,d,x,y);
return d == 1 ? (x%mod+mod)%mod : -1;
}
ll log_mod(ll a,ll b)
{
ll m,v,e=1,i;
m=(ll)sqrt(mod+0.5);
v=inv(fast_mod(a,m));
map<ll ,ll >x;
x.clear();
x[1]=0;
for(i=1;i<m;i++)
{
e=mul_mod(e,a);
if(!x.count(e))x[e]=i;
}
for(i=0;i<m;i++)
{
if(x.count(b))return i*m+x[b];
b=mul_mod(b,v);
}
return -1;
}
ll solve()
{
int temp=0;
for(int i=0;i<b;i++)
if(p[i].X!=maxx&&!s.count(make_pair(p[i].X+1,p[i].Y)))temp++;
temp+=n;
for(int i=0;i<b;i++)
if(p[i].X==1)temp--;
ll ret=mul_mod(fast_mod(k,temp),fast_mod(k-1,(long long)maxx*n-b-temp));
if(ret==r)return maxx;
temp=0;
for(int i=0;i<b;i++)if(p[i].X==maxx)temp++;
maxx++;
ret=mul_mod(ret,fast_mod(k,temp));
ret=mul_mod(ret,fast_mod(k-1,n-temp));
if(ret==r)return maxx;
//求(ret*((k-1)^n)^x)%mod=r
//即((k-1)^n)^x=r*(ret^(-1))%mod
return log_mod(fast_mod(k-1,n),mul_mod(r,inv(ret)))+maxx;
}

int main()
{
ios::sync_with_stdio(false);
int t;
//freopen("in.in","r",stdin);
cin>>t;
int cas=1;
while(t--)
{
maxx=1;
s.clear();
cin>>n>>k>>b>>r;
for(int i=0;i<b;i++)
{
cin>>p[i].X>>p[i].Y;
if(p[i].X>maxx)maxx=p[i].X;
s.insert(p[i]);
}
cout<<"Case "<<cas++<<": "<<solve()<<endl;
}
return 0;
}


代码君
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: