zoukankan      html  css  js  c++  java
  • LOJ2325. 「清华集训 2017」小 Y 和*的奴隶主【矩阵快速幂优化DP】【倍增优化】

    LINK


    思路

    首先是考虑怎么设计dp的状态
    发现奴隶主的顺序没有影响,只有生命和个数有影响,所以就可以把每个生命值的奴隶主有多少压缩成状态就可以了
    然后发现无论是什么时候一个状态到另一个状态的转移都是固定的方式
    所以可以预处理转移矩阵用矩阵快速幂进行优化

    但是如果在计算的时候暴力(状态^3)进行转移会TLE
    但是注意到在这个时候有用的状态其实只有一个向量
    所以就预处理倍增然后用向量乘矩阵来优化到单次(logn状态^2)就可以了

    有点卡常


    //Author: dream_maker
    #include<bits/stdc++.h>
    using namespace std;
    //----------------------------------------------
    //typename
    typedef long long ll;
    //convenient for
    #define fu(a, b, c) for (int a = b; a <= c; ++a)
    #define fd(a, b, c) for (int a = b; a >= c; --a)
    #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
    //inf of different typename
    const int INF_of_int = 1e9;
    const ll INF_of_ll = 1e18;
    //fast read and write
    template <typename T>
    void Read(T &x) {
      bool w = 1;x = 0;
      char c = getchar();
      while (!isdigit(c) && c != '-') c = getchar();
      if (c == '-') w = 0, c = getchar();
      while (isdigit(c)) x = (x<<1) + (x<<3) + c -'0', c = getchar();
      if (!w) x = -x;
    }
    template <typename T>
    void Write(T x) {
      if (x < 0) putchar('-'), x = -x;
      if (x > 9) Write(x / 10);
      putchar(x % 10 + '0');
    }
    //----------------------------------------------
    const int N = 170;
    const int Mod = 998244353;
    ll n, m, K, cnt = 0;
    int inv[10];
    int id[9][9][9];
    struct Matrix{
      int t[N][N];
      Matrix() { memset(t, 0, sizeof(t));}
    }trans, g[61];
    inline int add(int a, int b) { return ((a += b) > Mod) ? (a - Mod) : a; }
    inline int mul(int a, int b) { return 1ll * a * b % Mod; }
    Matrix operator * (const Matrix a, const Matrix b) {
      Matrix c;
      fu(k, 0, cnt)
        fu(i, 0, cnt) if (a.t[i][k])
          fu(j, 0, cnt)
            c.t[i][j] = add(c.t[i][j], mul(a.t[i][k], b.t[k][j]));
      return c;
    }
    inline Matrix mul_matrix(Matrix a, Matrix b) {
      Matrix c;
      fu(k, 0, cnt) if(a.t[0][k])
        fu(j, 0, cnt) 
          c.t[0][j] = add(c.t[0][j], mul(a.t[0][k], b.t[k][j]));
      return c;
    }
    inline int fast_pow(int a, int b) {
      int ans = 1;
      while (b) {
        if (b & 1) ans = mul(ans, a);
        b >>= 1;
        a = mul(a, a);
      }
      return ans;
    }
    inline int get_add_id(int i, int j, int k) {
      if (i + j + k == K) return id[i][j][k];
      if (m == 1) return id[i + 1][j][k];
      if (m == 2) return id[i][j + 1][k];
      if (m == 3) return id[i][j][k + 1];
    }
    void init() {
      fu(i, 1, K + 1)inv[i] = fast_pow(i, Mod - 2);
      int upj, upk, ID, inv_sum;
      fu(i, 0, K) {
        upj = (m == 1)? 0 : K - i;
        fu(j, 0, upj) {
          upk = (m == 2)? 0 : K - i - j; 
          fu(k, 0, upk) id[i][j][k] = ++cnt;
        }
      }
      ++cnt;
      trans.t[cnt][cnt] = 1;
      fu(i, 0, K) {
        upj = (m == 1)? 0 : K - i;
        fu(j, 0, upj) {
          upk = (m == 2)? 0 : K - i - j; 
          fu(k, 0, upk) {
            ID = id[i][j][k], inv_sum = inv[i + j + k + 1];
            if (i) trans.t[ID][id[i - 1][j][k]] = mul(inv_sum, i);
            if (j) trans.t[ID][get_add_id(i + 1, j - 1, k)] = mul(inv_sum, j);
            if (k) trans.t[ID][get_add_id(i, j + 1, k - 1)] = mul(inv_sum, k);    
            trans.t[ID][ID] = trans.t[ID][cnt] = inv_sum;
          }
        }
      }
      g[0] = trans;
      fu(i, 1, 60) g[i] = g[i - 1] * g[i - 1];
    }
    int main() {
    #ifdef dream_maker
      freopen("input.txt","r",stdin);
    #endif
      int T;Read(T);
      Read(m); Read(K);
      init();
      int pre = get_add_id(0, 0, 0);
      while (T--) {
        Read(n);
        Matrix ans;
        ans.t[0][pre] = 1;
        fu(i, 0, 60)
          if ((n >> i) & 1) ans = mul_matrix(ans, g[i]);
        printf("%d
    ", ans.t[0][cnt]);
      }
      return 0;
    }
    
  • 相关阅读:
    图像中的傅立叶变换(二)
    图像中的傅立叶变换(一)
    最大似然估计
    论文笔记:Batch Normalization
    TensorFlow学习笔记:共享变量
    postman管理收藏夹,批量执行接口
    postman设置token关联参数,其他接口直接读取token变量
    appium+python+unittest+HTMLRunner编写UI自动化测试集
    appium自动化环境搭建(python语言开发)
    Fiddler抓取https数据包
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9735969.html
Copyright © 2011-2022 走看看