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] ...
随机推荐
- Python数据可视化之matplotlib
常用模块导入 import numpy as np import matplotlib import matplotlib.mlab as mlab import matplotlib.pyplot ...
- IDEA+JSP+Servlet+Tomcat简单的登录示例
1.用IDEA新建Java WEB项目并配置Tomcat 这一部分可以参考之前的一篇随笔 https://www.cnblogs.com/lbhym/p/11496610.html 2.导入Servl ...
- tar使用笔记
解压到指定目录 -C tar -zxvf test.tar.gz -C /opt
- 逆向libbaiduprotect(三)- 移植python操作dalvik虚拟机c++函数,配合gdb控制程序运行流程
python编译移植到测试机,并且移植ctypes模块.利用ctypes代替c程序,利用dalvik内部c++函数,在运行过程中手动命令操控dalvik虚拟机,并结合gdb进行调试.绕过zygote和 ...
- [ch02-02] 非线性反向传播
系列博客,原文在笔者所维护的github上:https://aka.ms/beginnerAI, 点击star加星不要吝啬,星越多笔者越努力. 2.2 非线性反向传播 2.2.1 提出问题 在上面的线 ...
- 🔥《手把手教你》系列基础篇之3-python+ selenium-驱动浏览器和元素定位大法(详细)
1. 简介 上一篇中,只是简单地一带而过的说了一些驱动浏览器,这一篇继续说说驱动浏览器,然后再说一说元素定位的方法. 完成环境的安装并测试之后,我们对Selenium有了一定的了解了,接下来我们继续驱 ...
- 扛把子组final week 1/1 Scrum立会报告+燃尽图 01
此作业的要求参见http://edu.cnblogs.com/campus/nenu/2019fall/homework/10065 一.小组情况 队名:扛把子 组长:孙晓宇 组员:宋晓丽 梁梦瑶 韩 ...
- Res2net:多尺度骨干网络结构
<Res2Net: A New Multi-scale Backbone Architecture> 来自:南开大学程明明组 论文:https://arxiv.org/abs/1904.0 ...
- 新闻实时分析系统-HBase分布式集群部署与设计
HBase是一个高可靠.高性能.面向列.可伸缩的分布式存储系统,利用Hbase技术可在廉价PC Server上搭建 大规模结构化存储集群. HBase 是Google Bigtable 的开源实现,与 ...
- Linux -- 信号发送实现
信号是Linux系统响应某些条件而产生的一个事件,接收该信号的进程会响应地采取一些行动 signal 定义 在进程控制块 (PCB Process Control Block) 的数据结构中,存在 ...