• hdu5468 Puzzled Elena


    hdu5468 Puzzled Elena

    题意

    求一棵子树内与它互质的点个数

    解法

    容斥

    我们先求出与它不互质的数的个数,再用总数减去就好。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <vector>
    using namespace std;
    
    
    namespace Input {
        int a; char c; bool sign;
    
        inline int geti() {
            sign = false;
            while ((c = getchar()) < '0' || c > '9') sign |= c == '-';
            a = c - '0';
            while ((c = getchar()) >= '0' && c <= '9') a = (a << 3) + (a << 1) + c - '0';
            return sign ? -a : a;
        }
    }
    
    const int N = 1e5 + 5;
    vector<int> edge[N], Num[N], ty[N];
    int Cnt[N], Val[N], ans[N], ch[N][70];
    
    void init() {
        memset(Cnt, 1, sizeof Cnt);
        int i, j, cnt, len, t, k; cnt = 0;
        for (i = 0; i < N; ++i) Num[i].clear(), ty[i].clear();
        for (i = 2; i < N; ++i) {
            if (Cnt[i]) {
                for (j = i; j < N; j += i)
                  Cnt[j] = 0, Num[j].push_back(i), cnt += j == 4;
            }
        }
        vector<int>tmp;
        for (i = 2; i < N; ++i) {
            tmp.clear();
            for (j = 0; j < Num[i].size(); ++j)
              tmp.push_back(Num[i][j]);
            len = tmp.size(); Num[i].clear();
            for (j = 1; j < (1 << len); ++j) {
                cnt = 0, t = 1;
                for (k = 0; k < len; ++k)
                  if (j & (1 << k)) {
                      ++cnt; t *= tmp[k];
                  }
                if (cnt & 1) ty[i].push_back(-1);
                else ty[i].push_back(1);
                Num[i].push_back(t);
            }
        }
    }
    
    int dfs(int u, int fa) {
        int si = 0, va = Val[u], i, v;
        for (i = 0; i < Num[va].size(); ++i)
          ch[u][i] = Cnt[Num[va][i]];
        for (i = 0; i < edge[u].size(); ++i) {
            v = edge[u][i];
            if (v == fa) continue;
            si += dfs(v, u);
        }
        ans[u] = si;
        for (i = 0; i < Num[va].size(); ++i)
          ans[u] += Cnt[Num[va][i]] - ch[u][i];
        for (i = 0; i < Num[va].size(); ++i)
          Cnt[Num[va][i]] += ty[va][i];
        if (va == 1) ++ans[u];
        return si + 1;
    }
    
    int main() {
        init();
        int Case = 0, n, u, v, i;
        while (scanf("%d", &n) ^ EOF) {
            for (i = 1; i <= n; ++i) edge[i].clear();
            for (i = 1; i <  n; ++i) {
                u = Input::geti(), v = Input::geti();
                edge[u].push_back(v), edge[v].push_back(u);
            }
            memset(Cnt, 0, sizeof Cnt);
            for (i = 1; i <= n; ++i) Val[i] = Input::geti();
            dfs(1, 0);
            printf("Case #%d:", ++Case);
            for (i = 1; i <= n; ++i)
              printf(" %d", ans[i]);
            puts("");
        }
        return 0;
    }
    

    莫比乌斯反演

    此题其实也可以用莫比乌斯反演做,不过其实与容斥差不多,因为mu[i]其实与ty[i]是一样的。
    代码就不贴了,其实比较像。

  • 相关阅读:
    重装win7之后,wubi安装的ubuntu的启动菜单不见
    data_source.rb:182: TZInfo::DataSourceNotFound解决办法
    Gem::InstallerError:The 'json' native gem requires installed build tools
    去掉DL is deprecated, please use Fiddle警告信息
    ruby on rails安装(ubuntu 14.04)
    ruby on rails 安装(win8 64位)
    满城月季花开
    python中的zip()函数
    python学习之“序列”的理解
    二进制、十进制、八进制、十六进制的理解
  • 原文地址:https://www.cnblogs.com/cycleke/p/5838879.html
Copyright © 2020-2023  润新知