HDU4670 cube number on a tree(点分治+三进制加法)
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.
Input
The input contains several test cases, terminated by EOF.
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 P i(0 ≤ P i ≤ 10 15) 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.
Output
For each test case, print a number indicating the number of routes that satisfy the requirement.Sample Input
5
3 2 3 5
2500 200 9 270000 27
4 2
3 5
2 5
4 1
Sample Output
1
题解:
题意:给你一棵树,给你一些素数,给你每个点一个权值且每个权值均可由这些素数组成。现在定义任意任意两点的价值为他们路径上的权值相乘。求这样的点对的权值为立方数的个数
如果直接求得话会超int64,不可行
由立方数的性质可得,一个数可有素数组成,对于这些素数可以分解为这些素数相乘的形式如,24=(2^3)*(3^1);如果是立方数的话那么他的各进制对3取余都为0.股24可写成01这种三进制形式
对于这些权值的乘法可有三进制想加可得。
接下来就是树的分治了
当然这里可以先求出一条子树上的各个点的权值乘积,然后和根节点和其他字树比较看是否可以互补那么就找到一对
可用map容器实现。因为他重点是比较到根节点和其他子树是否可以互补,进而递归下去,求出每个子树的这样的点对
参考代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define fi first
#define se second
#define pii pair<int,int>
#define pil pair<int,ll>
#define mkp make_pair
#define pb push_back
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3fll;
inline ll read()
{
ll x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
const int maxn=1e5+;
ll n,k,head[maxn],tot,root,siz[maxn];
ll h[maxn][],pri[],fa[maxn],mx[maxn],S;
ll dep,ch[maxn][],fp[maxn],minn,nn;
bool vis[maxn];
map<ll,ll> mp;
struct Edge{
int v,nxt;
} edge[maxn<<]; inline void Init()
{
tot=;
memset(head,-,sizeof(head));
memset(h,,sizeof(h));
memset(mx,,sizeof(mx));
memset(siz,,sizeof(siz));
memset(vis,false,sizeof(vis));
} inline void AddEdge(ll u,ll v)
{
edge[tot].v=v;
edge[tot].nxt=head[u];
head[u]=tot++;
} inline void dfs1(ll u,ll fa)
{
nn++;
for(int e=head[u];~e;e=edge[e].nxt)
{
ll v=edge[e].v;
if(v==fa||vis[v]) continue;
dfs1(v,u);
}
} inline void GetRoot(ll u,ll fa)
{
siz[u]=;
ll tit=;
for(ll e=head[u];~e;e=edge[e].nxt)
{
ll v=edge[e].v;
if(v==fa||vis[v]) continue;
GetRoot(v,u);
siz[u]+=siz[v];
tit=max(tit,siz[v]);
}
tit=max(tit,nn-siz[u]);
if(tit<minn) minn=tit,root=u;
}
inline void dfs2(ll u,ll fa)
{
//cout<<"dfs2"<<endl;
if(fa==-)
{
for(ll i=;i<=k;++i)
ch[dep][i]=h[u][i];
}
else
{
ll e=fp[fa];
for(ll i=;i<=k;++i)
ch[dep][i]=(h[u][i]+ch[e][i])%;
}
fp[u]=dep++;
for(ll e=head[u];~e;e=edge[e].nxt)
{
ll v=edge[e].v;
if(v!=fa&&!vis[v]) dfs2(v,u);
}
} inline ll work(ll u)
{
ll s1=,ans=;
mp.clear();
for(ll i=;i<=k;++i) s1=s1*+h[u][i];
if(s1==) ans++;
mp[s1]=;
for(ll e=head[u];~e;e=edge[e].nxt)
{
ll v=edge[e].v;
if(vis[v]) continue;
dep=;dfs2(v,-);
for(ll i=;i<dep;++i)
{
s1=;
for(ll j=;j<=k;++j)
s1=s1*+(-ch[i][j])%;
ans+=mp[s1];
}
for(ll i=;i<dep;++i)
{
s1=;
for(ll j=;j<=k;++j)
s1=s1*+(ch[i][j]+h[u][j])%;
mp[s1]++;
}
}
return ans;
} inline ll dfs(ll u)
{
nn=,minn=inf;
dfs1(u,-);
GetRoot(u,-);
vis[root]=;
ll ans=work(root);
for(ll e=head[root];~e;e=edge[e].nxt)
{
ll v=edge[e].v;
if(vis[v]) continue;
ans+=dfs(v);
}
return ans;
} int main()
{
while(~scanf("%lld",&n))
{
Init();
k=read();
for(ll i=;i<=k;++i) pri[i]=read(); for(ll i=;i<=n;++i)
{
ll kk,val=read();
for(ll j=;j<=k;++j)
{
kk=;
while(val%pri[j]==)
{
++kk;
val/=pri[j];
kk%=;
}
h[i][j]=kk;
}
}
for(ll i=;i<n;++i)
{
ll x,y;
x=read();y=read();
AddEdge(x,y);AddEdge(y,x);
}
//cout<<"1"<<endl;
printf("%lld\n",dfs());
} return ;
}
HDU4670 cube number on a tree(点分治+三进制加法)的更多相关文章
- 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 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个素数 思路 ...
- HDU 4670 Cube number on a tree
divide and conquer on tree. #include <map> #include <vector> #include <cstdio> #in ...
- Square Number & Cube Number
Square Number: Description In mathematics, a square number is an integer that is the square of an in ...
- CodeChef - PRIMEDST Prime Distance On Tree 树分治 + FFT
Prime Distance On Tree Problem description. You are given a tree. If we select 2 distinct nodes unif ...
- 【BZOJ-1468】Tree 树分治
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1025 Solved: 534[Submit][Status][Discuss] ...
随机推荐
- [Office] 显示Office 2013中的Developer Tab和启用Macro
显示Developer Tab是对Office 2013进行开发的前提条件. 在Excel 2013中,打开Excel Option: 只要勾选对应的Developer选项即可显示该tab. 随着Of ...
- ThinkPHP 6.0 管道模式与中间件的实现分析
设计模式六大原则 开放封闭原则:一个软件实体如类.模块和函数应该对扩展开放,对修改关闭. 里氏替换原则:所有引用基类的地方必须能透明地使用其子类的对象. 依赖倒置原则:高层模块不应该依赖低层模块,二者 ...
- thinkphp 5.1 去掉 .html 后缀
thinkphp 5.1 去掉 .html 后缀
- React入门知识点清单
做前端的一定都知道现在是三大框架--Vue.React.Angular三足鼎立的时代.Vue是公认的最容易入门的,因为它文件结构上有传统的HTML的影子,让刚接触它的前端人员刚到很"亲切&q ...
- vux组件的样式变量的使用
使用x-header,查看文档发现有个样式变量,可以改变x-header的样式 这玩意怎么用呢? 1.在项目中创建一个.less样式文件,例如我这里是创建一个src/style/vux_theme.l ...
- Android、IOS的Fiddler证书安装教程
通过手机连接fiddler实现代理访问,其中必须得安装证书才能生效,那么针对不同的手机连接方式也不一样,分为两类:Android.iOS: Android-Fiddler证书安装: 直接在任意浏览器中 ...
- 【论文阅读】CornerNet: Detecting Objects as Paired Keypoints
以下内容将介绍ECCV2018的一篇目标检测的文章<CornerNet: Detecting Objects as Paired Keypoints>.该文章讲述了一个老子就是不用anch ...
- 新闻实时分析系统-Flume数据采集准备
Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据:同时,Flume提供对数据进行简单处理,并 ...
- 各种优化方法总结比较(sgd/momentum/Nesterov/adagrad/adadelta)
前言 这里讨论的优化问题指的是,给定目标函数f(x),我们需要找到一组参数x,使得f(x)的值最小. 本文以下内容假设读者已经了解机器学习基本知识,和梯度下降的原理. Batch gradient d ...
- vscode启动黑屏
今天打开vscode的时候突然就黑屏了,一脸懵 于是上网找了一下,根据这位博主的解决办法: https://blog.csdn.net/insgo/article/details/102975986 ...