zoukankan      html  css  js  c++  java
  • [bzoj3004][SDOI2012]吊灯——樹形DP

    Brief Description

    給定一棵樹, 判斷是否可以將其分成(frac{n}{k})個聯通塊, 其中每個聯通塊的大小均爲k.

    Algorithm Design

    我們有一個結論: k可行iff存在(frac{n}{k})個點, 以這些點爲根的子樹大小爲k或k的倍數.
    讀者可以自行yy一下證明.
    有了這個結論之後, 我們可以算出每個size, 用一個桶統計一下就好了.

    Code

    #include <algorithm>
    #include <cctype>
    #include <cstdio>
    #include <cstring>
    const int maxn = 1200000;
    int fa[maxn], n, divide[maxn], size[maxn], f[maxn], tot = 0;
    void fuck(int n) {
      int i;
      for (i = 1; i * i < n; i++) {
        if (n % i == 0) {
          divide[tot++] = i;
          divide[tot++] = n / i;
        }
      }
      if (i * i == n)
        divide[tot++] = i;
      std::sort(divide, divide + tot);
    }
    int main() {
      //  freopen("sdoi12_divide.in", "r", stdin);
      //  freopen("sdoi12_divide.out", "w", stdout);
      scanf("%d", &n);
      char ch = getchar();
      int cnt = 0;
      while (cnt < (n - 1)) {
        int x = 0;
        while (!isdigit(ch))
          ch = getchar();
        while (isdigit(ch)) {
          x = x * 10 + ch - '0';
          ch = getchar();
        }
        cnt++;
        fa[cnt + 1] = x;
      }
      fuck(n);
      for (int T = 1; T <= 10; T++) {
        printf("Case #%d:
    ", T);
        memset(size, 0, sizeof(size));
        memset(f, 0, sizeof(f));
        for (int i = 2; i <= n; i++) {
          if (T != 1) {
            fa[i] = (fa[i] + 19940105) % (i - 1) + 1;
          }
        }
        for (int i = n; i; i--)
          size[fa[i]] += ++size[i];
        for (int i = 1; i <= n; i++)
          f[size[i]]++;
        for (int i = 0; i < tot; i++) {
          int tmp = 0;
          for (int j = divide[i]; j <= n; j += divide[i])
            tmp += f[j];
          if (tmp == n / divide[i]) {
            printf("%d
    ", divide[i]);
          }
        }
      }
    }
    
  • 相关阅读:
    2020.4.26 resources
    Visual Studio M_PI定义
    12.3 ROS Costmap2D代价地图源码解读_1
    Delphi GDI对象之剪切区域
    用GDI+DrawImage画上去的图片会变大
    简单的GDI+双缓冲的分析与实现
    双缓冲绘图
    C++中的成员对象
    鼠标在某个控件上按下,然后离开后弹起,如何捕获这个鼠标弹起事件
    CStatic的透明背景方法
  • 原文地址:https://www.cnblogs.com/gengchen/p/6579442.html
Copyright © 2011-2022 走看看