Discription
There is a skyscraping tree standing on the playground of Nanjing University of Science and Technology. On each branch of the tree is an integer (The tree can be treated as a connected graph with N vertices, while each branch can 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 10 6 + 3) equals to K? 
Can you help them in solving this problem?

Input

There are several test cases, please process till EOF. 
Each test case starts with a line containing two integers N(1 <= N <= 10 5) and K(0 <=K < 10 6 + 3). The following line contains n numbers v i(1 <= v i < 10 6 + 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.

Output

For each test case, print a single line containing two integers a and b (where a < b), representing the two endpoints of the chain. If multiply solutions exist, please print the lexicographically smallest one. In case no solution exists, print “No solution”(without quotes) instead. 
For more information, please refer to the Sample Output below.

Sample Input

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

Sample Output

3 4
No solution

Hint

1. “please print the lexicographically smallest one.”是指: 先按照第一个数字的大小进行比较,若第一个数字大小相同,则按照第二个数字大小进行比较,依次类推。

2. 若出现栈溢出,推荐使用C++语言提交,并通过以下方式扩栈:
#pragma comment(linker,"/STACK:102400000,102400000") 点分治的模板题,记录一下一些信息就行了。本题因为是路径上的点权之积而不是边权之积,所以切记
不要漏了点分的根的权值或者把它乘了两次。
(感觉我点分的模板好垃圾啊,每次都得写好久,还容易写错hhh)
#include<bits/stdc++.h>
#define ll long long
#define maxn 100005
#define ha 1000003
using namespace std;
int to[maxn*],ne[maxn*],num;
int hd[maxn],n,m,pt1,pt2,siz[maxn];
int ni[ha+],now[ha+],val[maxn];
int mn,sz,root;
ll k;
bool done[maxn]; inline void init(){
ni[]=;
for(int i=;i<ha;i++) ni[i]=-ni[ha%i]*(ll)(ha/i)%ha+ha;
} int find_siz(int x,int fa){
int an=;
for(int i=hd[x];i;i=ne[i]) if(!done[to[i]]&&to[i]!=fa) an+=find_siz(to[i],x);
return an;
} void find_root(int x,int fa){
siz[x]=;
int bal=;
for(int i=hd[x];i;i=ne[i]) if(!done[to[i]]&&to[i]!=fa){
find_root(to[i],x);
siz[x]+=siz[to[i]];
bal=max(bal,siz[to[i]]);
}
bal=max(bal,sz-siz[x]);
if(bal<mn) mn=bal,root=x;
} int dis[maxn],tt,loc[maxn]; void get_deep(int x,int fa,ll dd){
dis[++tt]=dd,loc[tt]=x;
int hh=k*ni[dd]%ha,a1=now[hh],a2=x;
if(a1>a2) swap(a1,a2);
if(a2<=n){
if(a1<pt1) pt1=a1,pt2=a2;
else if(a1==pt1&&a2<pt2) pt2=a2;
}
for(int i=hd[x];i;i=ne[i]) if(!done[to[i]]&&to[i]!=fa){
get_deep(to[i],x,dd*(ll)val[to[i]]%ha);
}
} inline void calc(int pos){
int pre=tt;
get_deep(pos,pos,val[pos]);
for(int i=pre+;i<=tt;i++) now[dis[i]]=min(now[dis[i]],loc[i]);
} inline void work(int tree,int trsiz){
mn=<<,sz=trsiz,root=;
find_root(tree,tree);
done[root]=;
k=k*ni[val[root]]%ha; dis[tt=]=;
now[]=root;
for(int i=hd[root];i;i=ne[i]) if(!done[to[i]]){
calc(to[i]);
} for(int i=;i<=tt;i++) now[dis[i]]=;
k=k*val[root]%ha; for(int i=hd[root];i;i=ne[i]) if(!done[to[i]]){
work(to[i],find_siz(to[i],to[i]));
}
} int main(){
init();
memset(now,0x3f,sizeof(now)); while(scanf("%d%lld",&n,&k)==){
memset(done,,sizeof(done));
memset(hd,,sizeof(hd)),num=; pt1=pt2=<<;
for(int i=;i<=n;i++) scanf("%d",val+i);
int uu,vv;
for(int i=;i<n;i++){
scanf("%d%d",&uu,&vv);
to[++num]=vv,ne[num]=hd[uu],hd[uu]=num;
to[++num]=uu,ne[num]=hd[vv],hd[vv]=num;
} work(,n); if(pt1>n) puts("No solution");
else printf("%d %d\n",pt1,pt2);
} return ;
}
												

HDOJ 4812 D Tree的更多相关文章

  1. hdoj 4925 Apple tree 【最小割】

    题目:pid=4925">hdoj 4925 Apple tree 来源:2014 Multi-University Training Contest 6 题意:给出一个矩阵,然后每一 ...

  2. HDU 4812 D Tree 树分治+逆元处理

    D Tree Problem Description   There is a skyscraping tree standing on the playground of Nanjing Unive ...

  3. hdoj 4786 Fibonacci Tree【并查集+最小生成树(kruskal算法)】

    Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  4. hdu 4812 D Tree(树的点分治)

    D Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total ...

  5. HDU 4812 D Tree

    HDU 4812 思路: 点分治 先预处理好1e6 + 3以内到逆元 然后用map 映射以分治点为起点的链的值a 成他的下标 u 然后暴力跑出以分治点儿子为起点的链的值b,然后在map里查找inv[b ...

  6. HDU - 4812 D Tree 点分治

    http://acm.hdu.edu.cn/showproblem.php?pid=4812 题意:有一棵树,每个点有一个权值要求找最小的一对点,路径上的乘积mod1e6+3为k 题解:点分治,挨个把 ...

  7. HDU 4812 D Tree 树分区+逆+hash新位置

    意甲冠军: 特定n点树 K 以下n号码是正确的点 以下n-1行给出了树的侧. 问: 所以,如果有在正确的道路点图的路径 % mod  = K 如果输出路径的两端存在. 多条路径则输出字典序最小的一条. ...

  8. HDU 4812 D Tree 树分治

    题意: 给出一棵树,每个节点上有个权值.要找到一对字典序最小的点对\((u, v)(u < v)\),使得路径\(u \to v\)上所有节点权值的乘积模\(10^6 + 3\)的值为\(k\) ...

  9. HDU 4871 Shortest-path tree 最短路 + 树分治

    题意: 输入一个带权的无向连通图 定义以顶点\(u\)为根的最短路生成树为: 树上任何点\(v\)到\(u\)的距离都是原图最短的,如果有多条最短路,取字典序最小的那条. 然后询问生成树上恰好包含\( ...

随机推荐

  1. 【BZOJ 4565】 [Haoi2016]字符合并 区间dp+状压

    考试的时候由于总是搞这道题导致爆零~~~~~(神™倒序难度.....) 考试的时候想着想着想用状压,但是觉得不行又想用区间dp,然而正解是状压着搞区间,这充分说明了一件事,状压不是只是一种dp而是一种 ...

  2. 【BZOJ1458】士兵占领 最大流的模板题

    我们只要把他们可以有的限制用流量限制,再用两者关系限制一下就可以开心的跑了. #include <cstdio> #include <cstring> #include < ...

  3. centos7 mysql cluster集群搭建基于docker

    1.准备 mn:集群管理服务器用于管理集群的其他节点.我们可以从管理节点创建和配置集群上的新节点.重新启动.删除或备份节点. db2/db3:这是节点间同步和数据复制的过程发生的层. db4/db5: ...

  4. 7月24号day16总结

    一开始显示出现问题,js路径不能应用,因为用的是springMVC框架书写,所以有路径的保护和静态引用地址时需要注意的地方 今天进行了最后项目的优化,包括map清洗数据部分的代码和echarts显示的 ...

  5. Java之戳中痛点 - (3)三目运算符的两个操作数类型尽量一致

    先看一个例子: package com.test; public class TernaryOperator { public static void main(String[] args) { in ...

  6. js中Date()对象详解

    var myDate = new Date(); myDate.getYear(); //获取当前年份(2位) myDate.getFullYear(); //获取完整的年份(4位,1970-???? ...

  7. DP---背包问题

    http://www.hawstein.com/posts/dp-knapsack.html http://www.cnblogs.com/wwwjieo0/archive/2013/04/01/29 ...

  8. 通过 CLI 搭建 ghost

    参考: ghost 官网 系统架构说明 架构 架构说明 本实践将 web 接入, nodejs 服务, 数据库分离, 适合生产环境场景. nginx 接入请求, 反向代理后端 nodejs 服务 no ...

  9. 大话Linux内核中锁机制之原子操作、自旋锁【转】

    转自:http://blog.sina.com.cn/s/blog_6d7fa49b01014q7p.html 多人会问这样的问题,Linux内核中提供了各式各样的同步锁机制到底有何作用?追根到底其实 ...

  10. python 学习笔记 多进程

    要让python程序实现多进程,我们先了解操作系统的相关知识 Unix/Linux操作系统提供了一个fork()系统调用,他非常特殊,普通的函数调用,调用一次,返回一次,但是fork调用一次, 返回两 ...