zoukankan      html  css  js  c++  java
  • topcoder srm 711 div1

    problem1 link

    如果$n$满足,答案就是$n$。否则,依次枚举连续1的位置判断即可。

    problem2 link

    给出一个整数$X=prod_{i=0}^{n-1}p_{i}^{a_{i}}$,其中$p_{i}$表示第i个素数,比如$p_{0}=2,p_{1}=3$。问有多少有序数列使得数列中每个数字大于1且所有数字的乘积等于$X$。当$X=6$时有三个,分别是{2,3},{3,2},{6}。其中$1leq n leq 50,1leq a_{i} leq 50$。

    思路:令$f_{i}$表示将$X$表示成$i$个数乘积的方案数。那么$f_{i}=prod_{k=0}^{n-1}g(a_{k},i)-sum_{k=1}^{i-1}C_{i}^{k}f_{k}$。其中$g(i,j)$表示将$i$个苹果放在$j$个篮子里的方案数,$C_{i}^{j}$表示组合数。

    那么答案$ans=sum f_{i}$

    problem3 link

    https://codeforces.com/blog/entry/50573

    首先,枚舉第一個樹的邊,對後面每個樹,計算$dp[i][j]$,表示第$i$個樹選擇第$j$條邊的方案數.

    code for problem1

    #include <vector>
    
    class ConsecutiveOnes {
     public:
      long long get(long long n, int k) {
        constexpr int N = 50;
        std::vector<int> a(N + 1);
        a[0] = 0;
        for (int i = 1; i <= N; ++i) {
          a[i] = (n >> (i - 1)) & 1;
          a[i] += a[i - 1];
        }
        for (int i = k; i <= N; ++i) {
          if (a[i] - a[i - k] == k) {
            return n;
          }
        }
        long long ans = ((n >> k) << k) | ((1ll << k) - 1);
        long long curr = ans;
        for (int i = k; i < N; ++i) {
          if (((curr >> (i - k)) & 1) == 1) {
            curr ^= 1ll << (i - k);
          }
          curr |= 1ll << i;
          if (curr >= n && curr < ans) {
            ans = curr;
          }
        }
        return ans;
      }
    };

    code for problem2

    #include <vector>
    
    constexpr int N = 3005;
    constexpr int kMod = 1000000007;
    
    class OrderedProduct {
     public:
      int count(const std::vector<int> &a) {
        int s = 0;
        int n = static_cast<int>(a.size());
        for (int i = 0; i < n; ++i) {
          s += a[i];
        }
        std::vector<long long> dp(s + 1, 0);
        long long ans = 0;
        for (int i = 1; i <= s; ++i) {
          dp[i] = 1;
          for (int j = 0; j < n; ++j) {
            dp[i] = dp[i] * Get(a[j] + i - 1, i - 1) % kMod;
          }
          for (int j = 1; j < i; ++j) {
            dp[i] -= Get(i, j) * dp[j] % kMod;
            if (dp[i] < 0) {
              dp[i] += kMod;
            }
          }
          ans += dp[i];
        }
        return static_cast<int>(ans % kMod);
      }
    
      OrderedProduct() : c(N, std::vector<int>(N)) {
        c[0][0] = 1;
        for (int i = 1; i < N; ++i) {
          c[i][0] = 1;
          for (int j = 1; j < N; ++j) {
            c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
            c[i][j] %= kMod;
          }
        }
      }
    
     private:
      int Get(int a, int b) {
        if (a < b) return 0;
        return c[a][b];
      }
    
      std::vector<std::vector<int>> c;
    };

    code for problem3

    #include <algorithm>
    #include <unordered_map>
    #include <unordered_set>
    #include <vector>
    
    static constexpr int kMod = 1000000007;
    
    struct Tree {
      Tree(int root, int a, int b, int c, int n)
          : n(n),
            edges(n),
            father(n, std::vector<int>(10, -1)),
            depth(n),
            weight(n) {
        std::vector<int> x(n - 1);
        x[0] = c;
        for (int k = 1; k <= n - 2; ++k) {
          x[k] = (1ll * a * x[k - 1] + b) % kMod;
        }
        for (int j = 0; j <= n - 2; ++j) {
          int u = (root + j + 1) % n;
          int v = (root + (x[j] % (j + 1))) % n;
          if (u > v) {
            std::swap(u, v);
          }
          edges[u].emplace_back(v);
          edges[v].emplace_back(u);
        }
        Dfs(0, -1, 0);
        for (int i = 1; i < 10; ++i) {
          for (int j = 0; j < n; ++j) {
            int t = father[j][i - 1];
            if (t != -1) {
              father[j][i] = father[t][i - 1];
            }
          }
        }
      }
    
      int Lca(int u, int v) {
        int key = std::min(u, v) * n + std::max(u, v);
        {
          auto iter = lca_cache.find(key);
          if (iter != lca_cache.end()) {
            return iter->second;
          }
        }
        if (depth[u] > depth[v]) {
          std::swap(u, v);
        }
        for (int i = 9; i >= 0; --i) {
          if (depth[v] == depth[u]) {
            break;
          }
          int t = father[v][i];
          if (t == -1) {
            continue;
          }
          if (depth[t] >= depth[u]) {
            v = t;
          }
        }
        if (depth[v] != depth[u]) {
          v = father[v][0];
        }
        if (u == v) {
          lca_cache.emplace(key, u);
          return u;
        }
    
        for (int i = 9; i >= 0; --i) {
          int pu = father[u][i];
          int pv = father[v][i];
          if (pu == -1 || pu == pv) {
            continue;
          }
          u = pu;
          v = pv;
        }
        if (u != v) {
          u = father[u][0];
          v = father[v][0];
        }
        lca_cache.emplace(key, u);
        return u;
      }
    
      void Dfs(int u, int p, int d) {
        depth[u] = d;
        for (int x : edges[u]) {
          if (x != p) {
            father[x][0] = u;
            Dfs(x, u, d + 1);
          }
        }
      }
    
      void Clear() {
        for (int i = 0; i < n; ++i) {
          weight[i] = 0;
        }
      }
    
      void Add(int u, int v, int w) {
        int c = Lca(u, v);
        if (c == v) {
          weight[u] = Add(weight[u], w);
          weight[c] = Sub(weight[c], w);
        } else if (c == u) {
          weight[v] = Add(weight[v], w);
          weight[c] = Sub(weight[c], w);
        } else {
          weight[v] = Add(weight[v], w);
          weight[u] = Add(weight[u], w);
          weight[c] = Sub(weight[c], Add(w, w));
        }
      }
    
      void Compute(int u = 0, int p = -1) {
        for (int x : edges[u]) {
          if (x != p) {
            Compute(x, u);
            weight[u] = Add(weight[u], weight[x]);
          }
        }
      }
    
      void Sons(int u, int p, std::unordered_set<int> *son) {
        son->emplace(u);
        for (int x : edges[u]) {
          if (x != p) {
            Sons(x, u, son);
          }
        }
      }
    
      int Add(int x, int y) {
        x += y;
        if (x >= kMod) {
          x -= kMod;
        }
        return x;
      }
    
      int Sub(int x, int y) {
        x -= y;
        if (x < 0) {
          x += kMod;
        }
        return x;
      }
    
      int n;
      std::vector<std::vector<int>> edges;
      std::vector<std::vector<int>> father;
      std::vector<int> depth;
      std::unordered_map<int, int> lca_cache;
      std::vector<int> weight;
    };
    
    class TreeMoving {
     public:
      int count(int n, const std::vector<int> &roots, const std::vector<int> &a,
                const std::vector<int> &b, const std::vector<int> &c) {
        int m = static_cast<int>(roots.size());
        std::vector<Tree> trees;
        for (int i = 0; i < m; ++i) {
          trees.emplace_back(roots[i], a[i], b[i], c[i], n);
        }
        int result = 0;
        for (int u = 1; u < n; ++u) {
          int v = trees[0].father[u][0];
          trees[0].weight[u] = 1;
          for (int i = 1; i < m; ++i) {
            trees[i].Clear();
            for (int cu = 1; cu < n; ++cu) {
              int cv = trees[i - 1].father[cu][0];
              trees[i].Add(cu, cv, trees[i - 1].weight[cu]);
            }
            trees[i].Compute();
          }
          std::unordered_set<int> sons;
          trees[0].Sons(u, v, &sons);
          for (int cu = 1; cu < n; ++cu) {
            int cv = trees[m - 1].father[cu][0];
            if (sons.count(cu) + sons.count(cv) == 1) {
              result += trees[m - 1].weight[cu];
              result %= kMod;
            }
          }
          trees[0].weight[u] = 0;
        }
        return result;
      }
    };
  • 相关阅读:
    19_多态及引用类型的转化
    18_接口以及基本实现
    17_super关键字 超,基,父
    Static 关键字
    17_抽象类
    17_继承
    数 函数类 Math类
    ArrayList类 Arrays类 注释
    我的第一篇博客
    hdu 3478 Catch--二分图判断
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/6632050.html
Copyright © 2011-2022 走看看