zoukankan      html  css  js  c++  java
  • UVa 11916 (离散对数) Emoogle Grid

    因为题目要求同列相邻两格不同色,所以列与列之间不影响,可以逐列染色。

    如果一个格子的上面相邻的格子,已经被染色则染这个格子的时候,共有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

     1 #include <cstdio>
     2 #include <map>
     3 #include <set>
     4 #include <cmath>
     5 #include <algorithm>
     6 using namespace std;
     7 #define MP make_pair
     8 #define INS insert
     9 typedef long long LL;
    10 
    11 const int MOD = 100000007;
    12 const int maxb = 500 + 10;
    13 int n, m, k, b, r, x[maxb], y[maxb], fir_row;
    14 set<pair<int, int> > Set;
    15 
    16 int mul_mod(int a, int b)
    17 { return (LL) a * b % MOD; }
    18 
    19 int pow_mod(int a, LL n)
    20 {
    21     int ans = 1, base = a;
    22     while(n)
    23     {
    24         if(n & 1) ans = mul_mod(ans, base);
    25         base = mul_mod(base, base);
    26         n >>= 1;
    27     }
    28     return ans;
    29 }
    30 
    31 int inv(int a)
    32 { return pow_mod(a, MOD - 2); }
    33 
    34 int log_mod(int a, int b)
    35 {//a^x=b (mod MOD)
    36     int m, v, e = 1, i;
    37     m = (int)sqrt(MOD + 0.5);
    38     v = inv(pow_mod(a, m));
    39     map<int, int> x;
    40     x[1] = 0;
    41     for(i = 1; i < m; i++)
    42     {
    43         e = mul_mod(e, a);
    44         if(e == b) return i;
    45         if(!x.count(e)) x[e] = i;
    46     }
    47     for(i = 0; i < m; i++)
    48     {
    49         if(x.count(b)) return i*m + x[b];
    50         b = mul_mod(b, v);
    51     }
    52     return -1;
    53 }
    54 
    55 int solve()
    56 {
    57     int c = 0;//前m行涂k种颜色的格子个数
    58     for(int i = 0; i < b; i++)
    59         if(x[i] != m && !Set.count(MP(x[i] + 1, y[i]))) c++;
    60     c += n - fir_row;
    61     int cnt = mul_mod(pow_mod(k, c), pow_mod(k-1, (LL)m*n - b - c));
    62     if(cnt == r) return m;
    63 
    64     c = 0;//第m+1行涂k种颜色的格子个数
    65     for(int i = 0; i < b; i++) if(x[i] == m) c++;
    66     cnt = mul_mod(mul_mod(cnt, pow_mod(k, c)), pow_mod(k-1, n-c));
    67     if(cnt == r) return m + 1;
    68 
    69     int p = pow_mod(k-1, n);
    70     int v = inv(cnt);
    71     return log_mod(p, mul_mod(r, v)) + m + 1;
    72 }
    73 
    74 int main()
    75 {
    76     //freopen("in.txt", "r", stdin);
    77 
    78     int T;
    79     scanf("%d", &T);
    80     for(int kase = 1; kase <= T; kase++)
    81     {
    82         scanf("%d%d%d%d", &n, &k, &b, &r);
    83         Set.clear();
    84         m = 1; fir_row = 0;
    85         for(int i = 0; i < b; i++)
    86         {
    87             scanf("%d%d", &x[i], &y[i]);
    88             Set.INS(MP(x[i], y[i]));
    89             if(x[i] > m) m = x[i];
    90             if(x[i] == 1) fir_row++;//第一行不能被涂色的个数
    91         }
    92         printf("Case %d: %d
    ", kase, solve());
    93     }
    94 
    95     return 0;
    96 }
    代码君
  • 相关阅读:
    假如我国国民生产总值的年增长率为7%, 计算10年后我国国民生产总值与现在相比增长多少百分比。计算公式为$p = (1+r)^n$ ,其中r为年增长率,n为年数,p为与现在相比的倍数
    不定积分40例
    docker容器
    Kubernetes搭建
    windows提权之mimikatz
    NodeJS沙箱逃逸&&vm
    jwt攻击手段
    yii2邮件配置教程,报Expected response code 250 but got code "553"原因
    git 撤销,放弃本地修改
    动态规划(含最短路径和正则匹配例子)
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4322668.html
Copyright © 2011-2022 走看看