1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<map> #include<set> using namespace std;
typedef long long LL; const int mod = 1e8 + 7; set<pair<int, int> > best; int x[510],y[510];
LL qpow(LL x,LL n){ LL ans = 1; while(n){ if(n & 1) ans = ans * x % mod; x = x * x % mod; n >>= 1; } return ans; }
void exgcd(LL a,LL b, LL &d, LL &x, LL &y){ if(!b){x = 1; y = 0;d = a; return ;} exgcd(b, a %b, d, y, x); y-= a/b * x; }
LL inv(LL a){ LL x, y,d; exgcd(a,mod,d,x,y); return d == 1 ? (x + mod ) % mod : -1; }
int BSGS(LL x,LL r){ LL m =(LL)ceil(sqrt((double)mod+0.5)); LL v = inv(qpow(x,m)); map<LL,LL> q; map<LL,bool> vis; LL k = 1; vis[k] = 1; q[k] = 0; for(int i = 1; i < m; ++i){ k = k * x % mod; if(vis[k] == 0){ vis[k] = 1; q[k] = i; } }for(int i = 0; i< m; ++i){ if(vis[r]){ int ans = i * m +q[r]; return ans; } r =r * v % mod; } return -1; }
int main(){ int t; scanf("%d", &t); int kase = 0; while(t--){ LL b, n, k, r,num; int maxx; scanf("%I64d %I64d %I64d %I64d", &n, &k, &b, &r); maxx = 1;num = 0;best.clear(); for(int i = 1; i <= b ; ++i){ scanf("%I64d %I64d", &x[i], &y[i]); maxx= max(maxx,x[i]); best.insert(make_pair(x[i],y[i])); }for(int i= 1; i <= b; ++i) if(x[i] != maxx && !best.count(make_pair(x[i]+1,y[i]))) ++num; for(int i = 1; i <= b;++i) if(x[i] == 1) --num; num += n; LL sum = (qpow(k,num) * qpow(k - 1, maxx * n - b - num) ) % mod; if (sum == r) { printf("Case %d: %d\n",++kase, maxx); continue; }num = 0; for(int i = 1; i <= b; ++i) if(x[i] == maxx) ++num; ++maxx; sum = sum * qpow(k-1,n-num) % mod; sum = sum * qpow(k,num) % mod; if (sum == r){ printf("Case %d: %d\n",++kase, maxx ); continue; }LL x = qpow(k-1,n); r = r *inv(sum) % mod; int ans = maxx + BSGS(x,r); printf("Case %d: %d\n",++kase,ans); }return 0; }
|