程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 4670 Cube number on a tree

HDU 4670 Cube number on a tree

編輯:C++入門知識

#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\n", dac(0));  
  }  
  return 0;  
}  

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved