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\n", dac(0));
}
return 0;
}
HDU 4670 Cube number on a tree的更多相关文章
- hdu 4670 Cube number on a tree(点分治)
Cube number on a tree Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/ ...
- HDU 4670 Cube number on a tree ( 树的点分治 )
题意 : 给你一棵树 . 树的每一个结点都有一个权值 . 问你有多少条路径权值的乘积是一个全然立方数 . 题目中给了你 K 个素数 ( K <= 30 ) , 全部权值都能分解成这k个素数 思路 ...
- HDU4670 cube number on a tree(点分治+三进制加法)
The country Tom living in is famous for traveling. Every year, many tourists from all over the world ...
- HDU4670 Cube number on a tree 树分治
人生的第一道树分治,要是早点学我南京赛就不用那么挫了,树分治的思路其实很简单,就是对子树找到一个重心(Centroid),实现重心分解,然后递归的解决分开后的树的子问题,关键是合并,当要合并跨过重心的 ...
- 【点分治】【map】【哈希表】hdu4670 Cube number on a tree
求树上点权积为立方数的路径数. 显然,分解质因数后,若所有的质因子出现的次数都%3==0,则该数是立方数. 于是在模意义下暴力统计即可. 当然,为了不MLE/TLE,我们不能存一个30长度的数组,而要 ...
- [hdu4670 Cube number on a tree]点分治
题意:给一个N个带权节点的树,权值以给定的K个素数为因子,求路径上节点乘积为立方数的路径条数 思路:立方数的性质是每个因子的个数为3的倍数,那么每个因子只需要保存0-2三个状态即可,然后路径就可以转化 ...
- 主席树[可持久化线段树](hdu 2665 Kth number、SP 10628 Count on a tree、ZOJ 2112 Dynamic Rankings、codeforces 813E Army Creation、codeforces960F:Pathwalks )
在今天三黑(恶意评分刷上去的那种)两紫的智推中,突然出现了P3834 [模板]可持久化线段树 1(主席树)就突然有了不详的预感2333 果然...然后我gg了!被大佬虐了! hdu 2665 Kth ...
- hdu 2665 Kth number
划分树 /* HDU 2665 Kth number 划分树 */ #include<stdio.h> #include<iostream> #include<strin ...
- HDU - 3584 Cube (三维树状数组 + 区间改动 + 单点求值)
HDU - 3584 Cube Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Subm ...
随机推荐
- ucosII移植
移植ucos II 到一个芯片上,只需要修改下面三个文件:OS_CPU.H,OS_CPU_C.C,OS_CPU_A.ASM. 具体来说,移植主要包括以下几项内容 (1).OS_CPU.H :用#def ...
- web.xml中load-on-startup的作用(转)
web.xml中load-on-startup的作用 如下一段配置,熟悉DWR的再熟悉不过了:<servlet> <servlet-name>dwr-invoker< ...
- selinux --chcon命令
chcon命令:修改对象(文件)的安全上下文.比如:用户:角色:类型:安全级别. 命令格式: Chcon [OPTIONS…] CONTEXT FILES….. Chcon [OPTIONS…] –r ...
- hibernate封装查询,筛选条件然后查询
// 封装查询条件 @Test public void transmitParameter() { Map map = new HashMap<String, String>(); // ...
- html常用笔记
<?php //CSS可以对文本格式进行精确的控制 //HTML标记更有利于搜索引擎 //一.标签 <br> <p>//换行后插入一个空行,单字节不换行,双字节自动换行 ...
- Activity传递对象的方法
//Serializeable传递对象的方法 public void SerializeMethod(){ Person mPerson = new Person(); mPerson.setName ...
- 用vs2012的命令利用xsd文件生成对应的C#类,把xml的string类型映射到生成的类
输入命令: xsd d:\TDDOWNLOAD\atom-author-link.xsd /c /language:C# /outputdir:d:\ 含义: 将d:\TDDOWNLOAD\atom- ...
- Shell教程4-Shell替换
如果表达式中包含特殊字符,Shell 将会进行替换.例如,在双引号中使用变量就是一种替换,转义字符也是一种替换. 举个例子: 复制纯文本新窗口 #!/bin/bash a=10 echo -e & ...
- 工具栏ToolStrip能触发焦点控件的Leave、Validating、DataError等事件以验证数据 z
public class ToolStripEx : ToolStrip { protected override void OnClick(EventArgs e) { base.OnClick(e ...
- 【转】从外行的视角尝试讲解为什么这回丰田栽了【全文完】【v1.01】
转自:http://club.tgfcer.com/thread-6817371-1-1.html [第一部分]背景简介 前几年闹得沸沸扬扬的丰田刹不住事件最近又有新进展.十月底俄克拉荷马的一次庭审 ...