uva11916(数学题,模方程)

来源:互联网 发布:中山大学网络无法上 编辑:程序博客网 时间:2024/05/24 03:03

  题目的意思是有M*N列的格子,K种颜色,B个不能涂色的格子,涂色的约束条件是每一列相连的格子上不能是相同的颜色,然后总数Mod100000007的结果是等于R的,现在题目中告诉N,K,B,R,要求满足条件的最小M。

  解答:根据B个格子的坐标,可以求出最小的行minM,然后求对于minM*N的格子有多少种方案,然后再往外扩展一行,又有多少种方案,假设求得Mod完之后的结果为a,那么往后每添加一行,方案是当前的(k-1)^N次倍,即要求下面的方程解的最小值。

  ≡ 

  转化一下就是a^x ≡ b(Mod n)的模型

  

#include "stdio.h"#include "string.h"#include "math.h"#include <string>#include <queue>#include <stack>#include <vector>#include <map>#include <algorithm>#include <iostream>using namespace std;#define MAXM 1#define MAXN 1#define max(a,b) a > b ? a : b#define min(a,b) a < b ? a : b#define Mem(a,b) memset(a,b,sizeof(a))double pi = acos(-1.0);double eps = 1e-6;typedef struct{int f,t,w,next;}Edge;Edge edge[MAXM];int head[MAXN];int kNum;typedef long long LL;LL Mod = 100000007;void addEdge(int f, int t, int w){edge[kNum].f = f;edge[kNum].t = t;edge[kNum].w = w;edge[kNum].next = head[f];head[f] = kNum ++;}LL N, K, R, B;int T;typedef struct{int x, y;}BL;BL bl[505];bool comp(BL a, BL b){if( a.y == b.y )return a.x < b.x;return a.y < b.y;}LL pow_mod(LL a, LL m){if( m == 0 )return 1;LL ans = pow_mod(a, m/2) % Mod;ans = ans * ans % Mod;if( m % 2 )ans = ans * a % Mod;return ans;}void exgcd(LL a, LL b, LL &d, LL &x, LL &y){if( !b ){x = 1, y = 0;d = a;}else{exgcd(b, a % b, d, y, x);y -= x * ( a / b ) ;}}//求a在mod n下的逆LL inv(LL a){LL x, y, d;exgcd(a, Mod, d, x, y);return d == 1 ? (x + Mod) % Mod : -1;}//求解a^x = b(mod n)LL log_mod(LL a, LL b){LL m, v, e = 1;m = (LL)sqrt(Mod + 0.5);v = inv(pow_mod(a,m));map<LL, LL> x;x[1] = 0;for(int i = 1; i < m; i ++){e = e * a % Mod;if( !x.count(e) ) x[e] = i;}for(int i = 0; i < m; i ++){if( x.count(b) )return i * m + x[b];b = b * v % Mod;}return -1;}void solve(){int minM = 1;for(int i = 0; i < B; i ++){scanf("%d %d", &bl[i].x, &bl[i].y);if( minM < bl[i].x )minM = bl[i].x;}sort(bl, bl + B, comp);R = R % Mod;LL ans = 1, powK1 = N;for(int i = 0; i < B; i ++){if( bl[i].x == 1 )powK1 --;if( bl[i].x != minM ){if( i + 1 < B && bl[i+1].y == bl[i].y){if( bl[i].x + 1 != bl[i+1].x ){powK1 ++;}}else{powK1 ++;}}}ans = ans * pow_mod(K, powK1) % Mod;ans = ans * pow_mod(K-1, minM * N - powK1 - B) % Mod;if( ans == R ){printf("%d\n", minM);return;}powK1 = 0;for(int i = 0; i < B; i ++){if( bl[i].x == minM ){powK1 ++;}}ans = ans * pow_mod(K, powK1) % Mod;ans = ans * pow_mod(K-1, N - powK1) % Mod;if( ans == R ){printf("%d\n", minM + 1);return;}//LL x, y, d;//exgcd(ans, Mod, d, x, y);LL x = inv(ans) * R % Mod;//x = ( x * R + Mod * Mod ) % Mod;ans = pow_mod(K-1, N) % Mod;printf("%d\n", log_mod(ans, x) + minM + 1 );}int main(){//freopen("d:\\test.txt", "r", stdin);while(cin>>T){for(int i = 0; i < T; i ++){cin>>N>>K>>B>>R;printf("Case %d: ", i + 1);solve();}}return 0;}

0 0
原创粉丝点击