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教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...
随机推荐
- BZOJ 2631: tree( LCT )
LCT...略麻烦... -------------------------------------------------------------------------------- #inclu ...
- Eclipse使用技巧总结(一)
一.建立工作空间 如上图所示,可以建立新的工作空间,或者切换工作空间. 二.导入导出工作空间配置 三.设置行号 如图,用鼠标在坐变阴影部分右击弹出菜单,选中Show Line Numbers一项. 四 ...
- chrome 浏览器帐号登录不来,如何解决自己的书签
装系统前把 该目录下 C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default 的 Bookmarks 复制出 ...
- activebar的用法
效果图: 网站页面上弹出消息提示狂,用来提示重大事件. <script src="http://www.ijquery.cn/js/jquery-1.7.2.min.js"& ...
- django 新闻编辑笔记
url(r'^news_manage/edit/$',views.news_edit,name='edit') url配置 <a href="/management/news_mana ...
- JS 切换显示
<style> #hhh div { width:200px; height:200px; background:red; display:none; ...
- 基于visual Studio2013解决C语言竞赛题之0510求最大和
题目
- JAVAC 命令使用方法
结构 javac [ options ] [ sourcefiles ] [ @files ] 參数可按随意次序排列. options 命令行选项. sourcefiles 一个或多个要编译的源文件( ...
- in window js 未定义和undifined的区别
浏览器报错:未定义和undifined不是同一概念,前者是没有申明,后者是没有赋值. 1: <html> <body> <script> ...
- 斯坦福大学IOS开发课程笔记(第七课第一部分)
转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/31462099 作者:小马 这节课的内容太多,分两部分介绍.本节课主要是介绍怎样开发 ...