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/Others)
Total Submission(s): 1628 Accepted Submission(s): 382
There are n provinces in the country. According to the experiences from the tourists came before, every province has its own preference value. A route’s preference value from one province to another is defined as the product of all the preference value of the provinces on the route. It’s guaranteed that for each two provinces in the country there is a unique route from one to another without passing any province twice or more.
Tom is a boy crazy about cube number. A cube number is a positive integer whose cube root is also an integer. He is planning to travel from a province to another in the summer vacation and he will only choose the route with the cube number preference value. Now he want to know the number of routes that satisfy his strange requirement.
Each case begins with a number n ( 1 ≤ n ≤ 50000), the number of the provinces.
The second line begins with a number K (1 ≤ K ≤ 30), and K difference prime numbers follow. It’s guaranteed that all the preference number can be represented by the product of some of this K numbers(a number can appear multiple times).
The third line consists of n integer numbers, the ith number indicating the preference value Pi(0 ≤ Pi ≤ 1015) of the i-th province.
Then n - 1 lines follow. Each line consists of two integers x, y, indicating there is a road connecting province x and province y.
3 2 3 5
2500 200 9 270000 27
4 2
3 5
2 5
4 1
- hdu 4670 Cube number on a tree(点分治)
- problem:
- 在一棵树上,求多少条路径的点权值积为立方数
- solve:
- 和普通的求积为k的点对数很像.因为权值有10^15,所以用质因子来记录每个树的权值. 然后就是状态保存,因为当你知道当前子树的一条链时
- ,需要查找其它子树(同一根)是否有链与其对应使积为立方数. 质因子总共有30位,所以可以用一个longlong来记录状态,用map保存
- (递归所有重心,每次计算当前重心的所有情况)
- hhh-2016-08-24 09:42:56
- */
- #pragma comment(linker,"/STACK:124000000,124000000")
- #include <algorithm>
- #include <iostream>
- #include <cstdlib>
- #include <cstdio>
- #include <cstring>
- #include <vector>
- #include <math.h>
- #include <map>
- #define lson i<<1
- #define rson i<<1|1
- #define ll long long
- #define clr(a,b) memset(a,b,sizeof(a))
- #define scanfi(a) scanf("%d",&a)
- #define scanfl(a) scanf("%I64d",&a)
- #define key_val ch[ch[root][1]][0]
- #define inf 0x3FFFFFFFFFFFFFFFLL
- #define mod 1000003
- using namespace std;
- const ll xo = (1LL << 61)-1;
- const int maxn = 50010;
- int head[maxn];
- int n,k,s[maxn],f[maxn],root;
- int Size,tot;
- bool vis[maxn];
- ll factor[maxn][31],d[maxn][31],fac[31];
- int facnt;
- int id[maxn];
- ll val;
- struct node
- {
- int to;
- int next;
- } edge[maxn << 2];
- void ini()
- {
- clr(factor,0);
- clr(head,-1),clr(vis,0);
- clr(s,0);
- tot = 0;
- }
- void add_edge(int u,int v)
- {
- edge[tot].to = v,edge[tot].next = head[u],head[u] = tot++;
- }
- void get_root(int now,int fa)
- {
- int v;
- s[now] = 1,f[now] = 0;
- for(int i = head[now]; ~i; i = edge[i].next)
- {
- if((v=edge[i].to) == fa || vis[v])
- continue;
- get_root(v,now);
- s[now] += s[v];
- f[now] = max(f[now],s[v]);
- }
- f[now] = max(f[now],Size-s[now]);
- if(f[now] < f[root]) root = now;
- }
- int num;
- map<ll,ll> mp;
- ll make_hash(ll q[])
- {
- ll t = 0;
- for(int i = 0; i < facnt; i++)
- {
- t = t*3LL + q[i];
- }
- return t;
- }
- void dfs(int now,int fa)
- {
- int v;
- id[num++] = now;
- s[now] = 1;
- for(int i = head[now]; ~i; i = edge[i].next)
- {
- if( (v=edge[i].to) == fa || vis[v])
- continue;
- for(int j = 0; j < facnt; j++)
- {
- d[v][j] = (factor[v][j]+d[now][j])%3;
- }
- dfs(v,now);
- s[now] += s[v];
- }
- }
- ll ans = 0;
- ll tp[31];
- void Debug(ll t)
- {
- for(int i = 30; i >= 0; i--)
- {
- if(t & (1 << i))
- printf("1");
- else
- printf("0");
- }
- cout << endl;
- }
- void make_ans(int now,int cnt)
- {
- int v ;
- f[0] = Size = cnt;
- get_root(now,root = 0);
- vis[root] = 1;
- mp.clear();
- ll ts = make_hash(factor[root]);
- if(ts == 0)
- ans ++;
- for(int i = head[root]; ~i; i = edge[i].next)
- {
- if(vis[v = edge[i].to])
- continue;
- num = 0;
- for(int j = 0; j < facnt; j++)
- d[v][j] = factor[v][j];
- dfs(v,root);
- for(int j = 0; j < num; j++)
- {
- for(int t = 0; t < facnt; t++)
- {
- tp[t] = (d[id[j]][t] + factor[root][t])%3;
- }
- ll ta = make_hash(tp);
- if(ta == 0)
- {
- ans ++;
- }
- ta = 0;
- for(int t = 0; t < facnt; t++)
- ta = ta*3LL + (3LL-tp[t])%3;
- if(mp[ta] > 0)
- {
- ans += mp[ta];
- }
- }
- for(int j = 0; j < num; j++)
- {
- ll ta = make_hash(d[id[j]]);
- if(mp[ta] == -1)
- mp[ta] = 0;
- mp[ta] ++;
- }
- }
- for(int i = head[root]; ~i; i = edge[i].next)
- {
- if(vis[v = edge[i].to])
- continue;
- make_ans(v,s[v]);
- }
- }
- void make_fac(int u,ll cur)
- {
- ll t = cur;
- for(int i = 0; i < facnt; i++)
- {
- while(t % fac[i] == 0)
- {
- t /= fac[i];
- factor[u][i]++;
- }
- factor[u][i] %= 3;
- }
- }
- int main()
- {
- int n,u,v;
- // freopen("in.txt","r",stdin);
- while( scanfi(n) != EOF)
- {
- ini();
- scanfi(facnt);
- for(int i = 0; i < facnt; i++)
- scanfl(fac[i]);
- for(int i = 1; i<= n; i++)
- {
- scanfl(val);
- make_fac(i,val);
- }
- for(int i = 1; i < n; i++)
- {
- scanfi(u),scanfi(v);
- add_edge(u,v);
- add_edge(v,u);
- }
- ans =0;
- make_ans(1,n);
- printf("%I64d\n",ans);
- }
- return 0;
- }
hdu 4670 Cube number on a tree(点分治)的更多相关文章
- HDU 4670 Cube number on a tree
divide and conquer on tree. #include <map> #include <vector> #include <cstdio> #in ...
- 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),实现重心分解,然后递归的解决分开后的树的子问题,关键是合并,当要合并跨过重心的 ...
- [hdu4670 Cube number on a tree]点分治
题意:给一个N个带权节点的树,权值以给定的K个素数为因子,求路径上节点乘积为立方数的路径条数 思路:立方数的性质是每个因子的个数为3的倍数,那么每个因子只需要保存0-2三个状态即可,然后路径就可以转化 ...
- 【点分治】【map】【哈希表】hdu4670 Cube number on a tree
求树上点权积为立方数的路径数. 显然,分解质因数后,若所有的质因子出现的次数都%3==0,则该数是立方数. 于是在模意义下暴力统计即可. 当然,为了不MLE/TLE,我们不能存一个30长度的数组,而要 ...
- 主席树[可持久化线段树](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 ...
随机推荐
- vue内置指令详解——小白速会
指令 (Directives) 是带有 v- 前缀的特殊属性,职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM. 内置指令 1.v-bind:响应并更新DOM特性:例如:v-bi ...
- 一句话了解JAVA与大数据之间的关系
大数据无疑是目前IT领域的最受关注的热词之一.几乎凡事都要挂上点大数据,否则就显得你OUT了.如果再找一个可以跟大数据并驾齐驱的IT热词,JAVA无疑是跟大数据并驾齐驱的一个词语.很多人在提到大数据的 ...
- nyoj 矩形个数
矩形的个数 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 在一个3*2的矩形中,可以找到6个1*1的矩形,4个2*1的矩形3个1*2的矩形,2个2*2的矩形,2个3 ...
- JAVA_SE基础——40.super关键字
只要this关键字掌握了,super关键字不在话下,因为他们原理都差不多的.. this&super 什么是this,this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针 ...
- js的构造函数共用事例
在使用构造函数去实现一种功能时,我们有时候往往需要实现这个功能,会因此产生多个堆内对象.这样就会造成堆内存滥用.占用不该占用的空间.为此我们可以利用函数把共用的内容封装起来.放便我们的使用.很多东西其 ...
- cookieUtil
public class CookieUtil { /** * 设置cookie * @param name cookie名字 * @param value cookie值 * @param maxA ...
- restful架构风格设计准则(四)资源表示和资源访问
读书笔记,原文链接:http://www.cnblogs.com/loveis715/p/4669091.html,感谢作者! 一.资源表示 1.资源表示:使用 单数 vs. 复数 如果一个URL所对 ...
- jscript定时器,一直用的东西,你真的明白吗?
JavaScript定时器 JavaScript是一种解释型语言(边编译边执行),Js解析顺序是从上到下,然后将编译后的任务丢到一个事件队列中,然后事件内的函数会从上到下开始执行 setInterva ...
- 测试驱动开发实践4————testSave之新增文档分类
[内容指引] 1.确定"新增文档分类"的流程及所需的参数 2.根据业务规则设计测试用例 3.为测试用例赋值并驱动开发 一.确定"新增文档分类"的流程及所需的参数 ...
- Python实现简单的三级菜单
话不多说,直奔代码 # 要处理的字典 dic1 = { '北京': { '东城': { '沙河': ['沙河机场', '链家'], '天通苑': ['北方明珠', '天通尾货'] }, '朝阳': { ...