hdu 4812 D Tree(树的点分治)
D Tree
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 1687 Accepted Submission(s): 263
be treated as a vertex). Today the students under the tree are considering a problem: Can we find such a chain on the tree so that the multiplication of all integers on the chain (mod 106 + 3) equals to K?
Can you help them in solving this problem?
Each test case starts with a line containing two integers N(1 <= N <= 105) and K(0 <=K < 106 + 3). The following line contains n numbers vi(1 <= vi < 106 + 3), where vi indicates the integer on vertex i.
Then follows N - 1 lines. Each line contains two integers x and y, representing an undirected edge between vertex x and vertex y.
exists, print “No solution”(without quotes) instead.
For more information, please refer to the Sample Output below.
5 60
2 5 2 3 3
1 2
1 3
2 4
2 5
5 2
2 5 2 3 3
1 2
1 3
2 4
2 5
3 4
No solutionHint1. “please print the lexicographically smallest one.”是指: 先依照第一个数字的大小进行比較,若第一个数字大小同样,则依照第二个数字大小进行比較,依次类推。 2. 若出现栈溢出,推荐使用C++语言提交。并通过下面方式扩栈:
#pragma comment(linker,"/STACK:102400000,102400000")
pid=5068" target="_blank">5068
5067pid=5065" target="_blank">5065
5064 5062使得路径上的结点的乘积为k(0 <=K < 106 + 3).有多解输出字典序最小的解。
#include<algorithm>
#include<iostream>
#include<string.h>
#include<stdio.h>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=100010;
const int mod=1e6+3;
typedef long long ll;
ll inv[mod+10];
int val[maxn],ms[maxn],son[maxn],vis[maxn],cnt,kv;
int mp[mod+10],use[mod+10],ptr,pos,ans1,ans2;
struct node
{
int v;
node *next;
} ed[maxn<<1],*head[maxn];
void adde(int u,int v)
{
ed[cnt].v=v;
ed[cnt].next=head[u];
head[u]=&ed[cnt++];
}
void dfs(int fa,int u)
{
son[u]=1;
ms[u]=0;
for(node *p=head[u];p!=NULL;p=p->next)
{
if(p->v==fa||vis[p->v])
continue;
dfs(u,p->v);
son[u]+=son[p->v];
ms[u]=max(ms[u],son[p->v]);
}
}
void findroot(int fa,int u,int all)
{
ms[u]=max(ms[u],all-son[u]);
if(ms[u]<ms[pos])
pos=u;
for(node *p=head[u];p!=NULL;p=p->next)
{
if(p->v==fa||vis[p->v])
continue;
findroot(u,p->v,all);
}
}
void getroot(int u)
{
dfs(-1,u);
pos=u;
findroot(-1,u,son[u]);
}
void cal(int fa,int u,int mc)//计算答案
{
mc=(ll)mc*val[u]%mod;
int op=(ll)kv*inv[mc]%mod,a,b;
if(mp[op])
{
a=u,b=mp[op];
if(a>b)
swap(a,b);
if(a<ans1)
ans1=a,ans2=b;
else if(a==ans1&&b<ans2)
ans2=b;
}
for(node *p=head[u];p!=NULL;p=p->next)
{
if(p->v==fa||vis[p->v])
continue;
cal(u,p->v,mc);
}
}
void update(int fa,int u,int mc)//更新hash表
{
mc=(ll)mc*val[u]%mod;
if(!mp[mc])
use[ptr++]=mc,mp[mc]=u;
else
mp[mc]=min(mp[mc],u);
for(node *p=head[u];p!=NULL;p=p->next)
{
if(p->v==fa||vis[p->v])
continue;
update(u,p->v,mc);
}
}
void solve(int u)//每次处理一颗子树
{
int root,i;
getroot(u);
root=pos;
mp[val[root]]=root;
vis[root]=1,ptr=0;
for(node *p=head[root];p!=NULL;p=p->next)
{
if(vis[p->v])
continue;
cal(root,p->v,1);//计算子树路径
update(root,p->v,val[root]);
}
for(i=0;i<ptr;i++)
mp[use[i]]=0;
mp[val[root]]=0;
for(node *p=head[root];p!=NULL;p=p->next)
{
if(vis[p->v])
continue;
solve(p->v);
}
}
int main()
{
int n,i,u,v;
inv[1]=1;
for(i=2;i<mod;i++)//预处理逆元
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
while(~scanf("%d%d",&n,&kv))
{
for(i=1;i<=n;i++)
scanf("%d",&val[i]);
memset(head,0,sizeof head);
memset(vis,0,sizeof vis);
cnt=0;
for(i=1;i<n;i++)
{
scanf("%d%d",&u,&v);
adde(u,v);
adde(v,u);
}
ans1=ans2=INF;
solve(1);
if(ans1!=INF)
printf("%d %d\n",ans1,ans2);
else
printf("No solution\n");
}
return 0;
}
hdu 4812 D Tree(树的点分治)的更多相关文章
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- HDU 4812 D Tree 树分治
题意: 给出一棵树,每个节点上有个权值.要找到一对字典序最小的点对\((u, v)(u < v)\),使得路径\(u \to v\)上所有节点权值的乘积模\(10^6 + 3\)的值为\(k\) ...
- HDU 4812 D Tree 树分区+逆+hash新位置
意甲冠军: 特定n点树 K 以下n号码是正确的点 以下n-1行给出了树的侧. 问: 所以,如果有在正确的道路点图的路径 % mod = K 如果输出路径的两端存在. 多条路径则输出字典序最小的一条. ...
- 【poj1741】Tree 树的点分治
题目描述 Give a tree with n vertices,each edge has a length(positive integer less than 1001). Define dis ...
- HDU 4812 D Tree
HDU 4812 思路: 点分治 先预处理好1e6 + 3以内到逆元 然后用map 映射以分治点为起点的链的值a 成他的下标 u 然后暴力跑出以分治点儿子为起点的链的值b,然后在map里查找inv[b ...
- POJ1741——Tree(树的点分治)
1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...
- HDU - 4812 D Tree 点分治
http://acm.hdu.edu.cn/showproblem.php?pid=4812 题意:有一棵树,每个点有一个权值要求找最小的一对点,路径上的乘积mod1e6+3为k 题解:点分治,挨个把 ...
- HDU 4670 Cube number on a tree ( 树的点分治 )
题意 : 给你一棵树 . 树的每一个结点都有一个权值 . 问你有多少条路径权值的乘积是一个全然立方数 . 题目中给了你 K 个素数 ( K <= 30 ) , 全部权值都能分解成这k个素数 思路 ...
- HDU 3333 - Turing Tree (树状数组+离线处理+哈希+贪心)
题意:给一个数组,每次查询输出区间内不重复数字的和. 这是3xian教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...
随机推荐
- 【MongoDB】windows平台搭建Mongo数据库复制集(相似集群)(一)
Replica Sets(复制集)是在mongodDB1.6版本号開始新增的功能.它能够实现故障自己主动切换和自己主动修复功能成员节点的功能,各个DB之间的数据全然一致,大大减少了单点故障的风险. ...
- VMware-WorkStation 去掉VM工具栏
链接地址:http://jingyan.baidu.com/article/8275fc86b95c6246a03cf629.html VMware 是目前用得最多的虚拟机.当开启虚拟机的全屏模式时, ...
- Palindromes _easy version
Palindromes _easy version Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav ...
- pay包注释(二)
@login_required()def to_register(request): return render_to_response("pay/register_yeepay.ht ...
- django email用法
在settings里面设置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'EMAIL_PORT = 25EMAIL_HOST ...
- javaScript 网页特效 输出语句
大家好,我是小强老师,今天主要讲解 三个最为常用的输出语句. alert() 弹出警示框 window.alert(‘继续学习’); 完整的写法 效果如下: 因为alert 属于window 对象 ...
- Android学习笔记:多个AsyncTask实例的并发问题
AsyncTask是Android给开发者提供的一个简单轻量级的多线程类,通过它我们可以很容易新建一个线程让在后台做一些耗时的操作(如IO操作.网络访问等),并在这个过程中更新UI.之所以说它轻量级, ...
- 基于visual Studio2013解决算法导论之051区间树
题目 区间树 解决代码及点评 #include <stdio.h> #include <string.h> #include <iostream> #def ...
- Android Cocos2d-x游戏集成友盟社会化组件分享功能
最近在帮助开发者集成友盟社会化组件的过程中,发现游戏的集成过程遇到一些困难,而Cocos2d-x具有较好的代表性,因此整理了一篇关于Android Cocos2d-x游戏集成友盟社会化组件指南,由于本 ...
- Ubuntu 12.04 安装JDK 8和Eclipse
Ubuntu 12.04 下安装 JDK8 方法一:(缺点是安装时附加openjdk等大量程序并无法去除,长处是安装简单) $ sudo apt-get install eclipse 方法二:(长处 ...