UVa 11916 (离散对数) Emoogle Grid
2015-03-09 06:46
295 查看
因为题目要求同列相邻两格不同色,所以列与列之间不影响,可以逐列染色。
如果一个格子的上面相邻的格子,已经被染色则染这个格子的时候,共有k-1中选择。
反过来,如果一个格子位于第一列,或者上面相邻的格子是不能被染色的格子,则共有k中选择。
虽然,矩阵的行数不定,但至少为所有不能被染色格子行标的最大值m。
分别检验一下染m行和m+1行的方案数(mod 100000007)是否为r
否则的话,后面每染一行方案数都会乘p = (k-1)n,假设前面计算出来的m+1行方案数为cnt
下面的任务就是求解 px * cnt = r (mod MOD),两边乘cnt的逆,得 px = r * cnt-1 (mod MOD)
最后加上前面的m+1行,答案为x + m + 1
最后吐槽一下我认为的坑点=_=,看到那个模想当然地以为是1e9+7,但是最后一个样例调了好久没过,后来才发现题中给的模是1e8+7
代码君
如果一个格子的上面相邻的格子,已经被染色则染这个格子的时候,共有k-1中选择。
反过来,如果一个格子位于第一列,或者上面相邻的格子是不能被染色的格子,则共有k中选择。
虽然,矩阵的行数不定,但至少为所有不能被染色格子行标的最大值m。
分别检验一下染m行和m+1行的方案数(mod 100000007)是否为r
否则的话,后面每染一行方案数都会乘p = (k-1)n,假设前面计算出来的m+1行方案数为cnt
下面的任务就是求解 px * cnt = r (mod MOD),两边乘cnt的逆,得 px = r * cnt-1 (mod MOD)
最后加上前面的m+1行,答案为x + m + 1
最后吐槽一下我认为的坑点=_=,看到那个模想当然地以为是1e9+7,但是最后一个样例调了好久没过,后来才发现题中给的模是1e8+7
#include <cstdio> #include <map> #include <set> #include <cmath> #include <algorithm> using namespace std; #define MP make_pair #define INS insert typedef long long LL; const int MOD = 100000007; const int maxb = 500 + 10; int n, m, k, b, r, x[maxb], y[maxb], fir_row; set<pair<int, int> > Set; int mul_mod(int a, int b) { return (LL) a * b % MOD; } int pow_mod(int a, LL n) { int ans = 1, base = a; while(n) { if(n & 1) ans = mul_mod(ans, base); base = mul_mod(base, base); n >>= 1; } return ans; } int inv(int a) { return pow_mod(a, MOD - 2); } int log_mod(int a, int b) {//a^x=b (mod MOD) int m, v, e = 1, i; m = (int)sqrt(MOD + 0.5); v = inv(pow_mod(a, m)); map<int, int> x; x[1] = 0; for(i = 1; i < m; i++) { e = mul_mod(e, a); if(e == b) return i; 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; } int solve() { int c = 0;//前m行涂k种颜色的格子个数 for(int i = 0; i < b; i++) if(x[i] != m && !Set.count(MP(x[i] + 1, y[i]))) c++; c += n - fir_row; int cnt = mul_mod(pow_mod(k, c), pow_mod(k-1, (LL)m*n - b - c)); if(cnt == r) return m; c = 0;//第m+1行涂k种颜色的格子个数 for(int i = 0; i < b; i++) if(x[i] == m) c++; cnt = mul_mod(mul_mod(cnt, pow_mod(k, c)), pow_mod(k-1, n-c)); if(cnt == r) return m + 1; int p = pow_mod(k-1, n); int v = inv(cnt); return log_mod(p, mul_mod(r, v)) + m + 1; } int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d", &T); for(int kase = 1; kase <= T; kase++) { scanf("%d%d%d%d", &n, &k, &b, &r); Set.clear(); m = 1; fir_row = 0; for(int i = 0; i < b; i++) { scanf("%d%d", &x[i], &y[i]); Set.INS(MP(x[i], y[i])); if(x[i] > m) m = x[i]; if(x[i] == 1) fir_row++;//第一行不能被涂色的个数 } printf("Case %d: %d\n", kase, solve()); } return 0; }
代码君
相关文章推荐
- 【离散对数 && 逆元 && 概率论】UVA - 11916 Emoogle Grid
- [离散对数] uva 11916 Emoogle Grid
- UVa 11916 - Emoogle Grid (离散对数)
- UVA 11916 Emoogle Grid 离散对数 大步小步算法
- UVA - 11916 Emoogle Grid (离散对数取模)
- [离散对数] uva 11916 Emoogle Grid
- UVA 11916 Emoogle Grid(离散对数、BSGS算法)
- UVA 11916 Emoogle Grid(大步小步算法(解模方程对数) 快速幂 模的逆)
- uva 11916 Emoogle Grid (BSGS)
- UVA 11916 Emoogle Grid(同余模)
- uva11916 Emoogle Grid
- uva 11916 - Emoogle Grid(大步小步算法)
- UVA11916 Emoogle Grid
- UVA 11916 - Emoogle Grid(数论)
- uva11916 - Emoogle Grid 网格涂色
- (UVA)11916 Emoogle Grid
- UVA 11916 Emoogle Grid 数论
- [uva 11916]Emoogle Grid 数学 BSGS
- [uva11916] Emoogle Grid (离散对数)
- uva 10913 - Walking on a Grid