zoukankan      html  css  js  c++  java
  • HDU 4670 Cube number on a tree

    divide and conquer on tree.

    #include <map>
    #include <vector>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int N = 5e4+10;
    const int K = 32;
    typedef long long LL;
    
    struct edge_t {
      int v, to;
    };
    vector<edge_t> E;
    int L[N];
    void init(int n) {
      E.clear();
      memset(L, -1, sizeof(int)*n);
    }
    void add_edge(int u, int v) {
      edge_t t = {v, L[u]};
      L[u] = E.size();
      E.push_back(t);
    }
    
    int n, k;
    LL w[N], p[K];
    
    LL ll_split(LL x) {
      LL rv = 0;
      for (int i = 0; i < k; i++) {
        LL o = 0;
        for ( ; x%p[i] == 0; x/= p[i]) o++;
        rv |= o%3<<(i<<1);
      }
      return rv;
    }
    LL ll_add(LL lhs, LL rhs) {
      LL rv = 0;
      for (int i = 0; i < k; i++) {
        LL o = ((lhs>>(i<<1)&3)+(rhs>>(i<<1)&3))%3;
        rv |= o<<(i<<1);
      }
      return rv;
    }
    LL ll_com(LL x) {
      LL rv = 0;
      for (int i = 0; i < k; i++) {
        rv |= (3-(x>>(i<<1)&3))%3<<(i<<1);
      }
      return rv;
    }
    void ll_show(LL x) {
      for (int i = 0; i < k; i++) {
        printf("%lld ", x>>(i<<1)&3);
      }
    }
    
    bool vis[N];
    int size, s[N];
    void get_size(int u) {
      vis[u] = 1;
      s[u] = 1;
      for (int i = L[u]; ~i; i = E[i].to) {
        int v = E[i].v;
        if (vis[v]) continue;
        get_size(v);
        s[u] += s[v];
      }
      vis[u] = 0;
    }
    int core;
    void find_core(int u) {
      vis[u] = 1;
      int flag = 1;
      for (int i = L[u]; ~i; i = E[i].to) {
        int v = E[i].v;
        if (vis[v]) continue;
        if (s[v] > size/2) flag = 0;
        find_core(v);
      }
      if (flag && size-s[u] <= size/2) core = u;
      vis[u] = 0;
    }
    vector<LL> dis;
    void get_dis(int u, LL d) {
      vis[u] = 1;
      dis.push_back(ll_add(w[u], d));
      for (int i = L[u]; ~i; i = E[i].to) {
        int v = E[i].v;
        if (vis[v]) continue;
        get_dis(v, ll_add(w[u], d));
      }
      vis[u] = 0;
    }
    int dac(int u) {
      get_size(u);
      size = s[u];
      if (size == 1) return !w[u];
      find_core(u);
      int rv = !w[u = core];
      vis[u] = 1;
      map<LL, int> m;
      m[0]++;
      for (int i = L[u]; ~i; i = E[i].to) {
        int v = E[i].v;
        if (vis[v]) continue;
        dis.clear();
        get_dis(v, 0);
        for (int j = 0; j < dis.size(); j++) {
          map<LL, int>::iterator it = m.find(ll_com(ll_add(dis[j], w[u])));
          if (it != m.end()) rv += it->second;
        }
        for (int j = 0; j < dis.size(); j++) m[dis[j]]++;
      }
      for (int i = L[u]; ~i; i = E[i].to) {
        int v = E[i].v;
        if (vis[v]) continue;
        rv += dac(v);
      }
      vis[u] = 0;
      return rv;
    }
    
    int main() {
      for ( ; ~scanf("%d", &n); ) {
        init(n);
        scanf("%d", &k);
        for (int i = 0; i < k; i++) {
          char b[32];
          scanf("%s", b);
          p[i] = atoll(b);
        }
        for (int i = 0; i < n; i++) {
          char b[32];
          scanf("%s", b);
          w[i] = ll_split(atoll(b));
        }
        for (int i = 0; i < n-1; i++) {
          int u, v;
          scanf("%d%d", &u, &v);
          u--, v--;
          add_edge(u, v);
          add_edge(v, u);
        }
        printf("%d
    ", dac(0));
      }
      return 0;
    }
    


  • 相关阅读:
    js window对象
    js 静态私有变量
    [WPF][ListBox]鼠标拖拽多选,(Shift Key、Ctrl Key多选有效)(转)
    GitLab关于SSH的使用
    Git命令--保存用户名和密码
    正则表达式
    WPF创建SignalR服务端(转)
    wpf学习之(IValueConverter)
    silverlight数据绑定模式TwoWay,OneWay,OneTime的研究
    WPF样式学习三
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3262863.html
Copyright © 2011-2022 走看看