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 ...
随机推荐
- 冲刺NO.2
Alpha冲刺第二天 站立式会议 项目进展 团队成员在确定了所需技术之后,开始学习相关技术的使用,其中包括了HTML5,CSS与SSH框架等开发技术.并且在项目分工配合加以总结和完善,对现有发现的关于 ...
- 团队作业4——第一次项目冲刺(Alpha版本)2017.11.19
第三次会议:2017-11-16 第二次会议讨论的还没有完全实现,于是在第三次会议上对此进行了一些对我们工作上的看法,得出结论:多花时间啊!!!! 又没照照片图: 会议主要内容: 1.登录注册完善 2 ...
- 0基础菜鸟学前端之Vue.js
简介:0基础前端菜鸟,啃了将近半月前端VUE框架,对前端知识有了初步的了解.下面总结一下这段时间的学习心得. 文章结构 前端基础 Vue.js简介 Vue.js常用指令 Vue.js组件 Vue.js ...
- img加载卡顿,解决办法
我觉得我在这个项目里遇到了太多的第一次.比如上一篇博文:在在360.UC等浏览器,img不加载原因. 当前情况是:图片加载缓慢,图片加载时出现卡顿. 上图:我缩放了图片,估计有点变形.能说明情况就行, ...
- .NET Core/.NET之Stream简介
之前写了一篇C#装饰模式的文章提到了.NET Core的Stream, 所以这里尽量把Stream介绍全点. (都是书上的内容) .NET Core/.NET的Streams 首先需要知道, Syst ...
- mysql数据库的三范式的设计与理解
一般的数据库设计都需要满足三范式,这是最基本的要求的,最高达到6NF,但是一般情况下3NF达到了就可以 一:1NF一范式的理解: 1NF是关系型数据库中的最基本要求,就是要求记录的属性是原子性,不可分 ...
- LeetCode题型分类及索引
目录 这是一个对LeetCode题目归类的索引,分类标准参考了July大神的<编程之法>以及LeetCode的tag项.分类可能还不太合理,逐步完善,请见谅~ 题主本人也在一点一点的刷题, ...
- pdf解析与结构化提取
#PDF解析与结构化提取##PDF解析对于PDF文档,我们选择用PDFMiner对其进行解析,得到文本.###PDFMinerPDFMiner使用了一种称作lazy parsing的策略,只在需要的时 ...
- Class-Based-View(CBV)
我们都知道,Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承.封装.多态).所以Django在后来加入了Class-Based-View.可以让我们用类写V ...
- 作业三:模拟 mysql 进行增删改查
# !/usr/bin/env python3 # _*_coding:utf-8_*_ def help_sql(cmd): if cmd in func_dic.keys(): print('{} ...