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教主的题. 用前缀和的思想可以轻易求得区间的和,但是对于重复数字这点很难处理.在线很难下手,考虑离线处理. 将所有查询区间从右端点由 ...
随机推荐
- ASP.NET站点安全
<configuration> <appSettings/> <connectionStrings> <add name="MyBookShop&q ...
- 打印NSLog分类 Foundation+Log.m
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @implementation UIView(Log) + ...
- java生成压缩图
链接地址:http://blog.sina.com.cn/s/blog_407a68fc0100nrba.html package util; import java.awt.image.Buffer ...
- javascript面向对象创建高级 Web 应用程序
目录 JavaScript 对象是词典 JavaScript 函数是最棒的 构造函数而不是类 原型 静态属性和方法 闭包 模拟私有属性 从类继承 模拟命名空间 应当这样编写 JavaScript ...
- ZOJ 1450 Minimal Circle 最小圆覆盖
套了个模板直接上,貌似没有随机化序列 QAQ //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #in ...
- atlas z 轴
问题源自一个帖子,因为上传的图比较多,就另开了这个贴写下自己的试验结果,原帖在下面链接中 http://game.ceeger.com/forum/read.php?tid=8911#info NGU ...
- 设计模式 ( 十三 ) 命令模式Command(对象行为型)
设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需 ...
- spider-web 是爬虫的网页版,使用xml配置
spider-web 是爬虫的网页版,使用xml配置,支持大部分页面的爬取,支持爬取内容的保存.下载等. 其中配置文件格式为: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1 ...
- 清华申请退学博士作品:完全用Linux工作,凸Windows
清华申请退学博士作品:完全用Linux工作 按尽管我们已经不习惯看长篇大论, 但我还是要说, 这是一篇值得你从头读到尾的长篇文章. 2005年9月22日,清华在读博士生王垠在水木社区BLOG上发表了& ...
- win7下wordPress本地搭建博客详解(深度亲测整理---傻瓜式详细教程)
搭建一个wordPress作为一个个人博客本来是特别简单的事情,但是网上的各种转载让初学者举步维艰,我就本身条件而言,会java EE,懂mysql都花费了我好长时间才搭建好本地博客. 注意:这个是本 ...