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] ...
随机推荐
- Ubuntu编译安装HAprox+Keepalived+MySQL负载高可用架构(结合Docker容器配置)
系统环境:Ubuntu16.04(Docker容器) 架构环境: Keepalived/HAproxy MASTER: 172.17.0.4 Keepalived/HAproxy BACKUP: 17 ...
- PHP 在Swoole中使用双IoC容器实现无污染的依赖注入
简介: 容器(container)技术(可以理解为全局的工厂方法), 已经是现代项目的标配. 基于容器, 可以进一步实现控制反转, 依赖注入. Laravel 的巨大成功就是构建在它非常强大的IoC容 ...
- MySQL InnoDB 实现高并发原理
MySQL 原理篇 MySQL 索引机制 MySQL 体系结构及存储引擎 MySQL 语句执行过程详解 MySQL 执行计划详解 MySQL InnoDB 缓冲池 MySQL InnoDB 事务 My ...
- 资深架构师Sum的故事:(Mysql)InnoDB下,存储过程中事务的处理
| 故事背景 话说有一回,X市X公司的产品经理Douni兴致冲冲的跑来和Sum(Sum,X市X公司资历8年程序猿,技能:深思.熟虑.心细.深究.技术过敏.口头禅:嗯,容我想想.坚信:只要赚钱的业务,我 ...
- PHP 提交复选框数据
PHP 提交复选框数据 前台,name要加 []: <input type="checkbox" name="cate[]" value="ca ...
- 微擎 manifest.xml
微擎 manifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns= ...
- Python3.7.1学习(八) Python访问SQL Server数据库
一.pip install pymssql即可安装pymssql库 二.Python连接SQL Server数据库 实例代码如下: # -*- coding:utf-8 -*-"&q ...
- linux下制作linux系统盘(光盘、U盘)
cdrecord制作启动光盘 首先cdrecord -scanbus输出设备列表和标识,(我的此次为5,0,0) [ˈrekərd] 然后用cdrecord -v dev=5,0,0 -eject ...
- ffmpeg-3.1.4居然也有这么坑的bug
近日自己用下载的ffmpeg-3.1.4代码自己编译来用,没想到会碰到这么一下低级坑.我用自己的编译出来的库总是会在用rtsp上传视频时崩掉,起初我还以为自己编译的x264出问题,因为我是绕开使用pk ...
- 数据库05 使用percona软件来进行数据备份
1.为什么要与用percona来备份 常见的MySQL备份工具 —跨平台性差 —备份时间长.冗余备份.浪费存储空间 mysqldump备份缺点: —效率较低.备份与还原速度慢,锁表(即备份数据库中的一 ...