HDU 4812 D Tree 树分治+逆元处理
D Tree
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.
For more information, please refer to the Sample Output below.
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
No solution
1. “please print the lexicographically smallest one.”是指: 先按照第一个数字的大小进行比较,若第一个数字大小相同,则按照第二个数字大小进行比较,依次类推。
2. 若出现栈溢出,推荐使用C++语言提交,并通过以下方式扩栈:
#pragma comment(linker,"/STACK:102400000,102400000")
题意:
给你一棵树n个点,一个K
让你找到一条 a->b 的字典数最小的 路径满足 这条路径 上点权 乘积取mod下 等于K
题解:
预处理小于mod的 所有逆元
树分治 即可
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
using namespace std; #pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair typedef long long LL;
const long long INF = 1e18;
const double Pi = acos(-1.0);
const int N = 1e5+, M = 1e6+, inf = 2e9, mod = ; int head[N],vis[N],f[N],siz[N],id[N],n,t = ,ansl,ansr,allnode,root; struct edge{int to,next;}e[N * ];
LL mp[M],inv[M],v[M],K,deep[M];
void add(int u,int v) {e[t].next=head[u];e[t].to=v;head[u]=t++;} void getroot(int u,int fa) {
f[u] = ;
siz[u] = ;
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(vis[to] || to == fa) continue;
getroot(to,u);
siz[u] += siz[to];
f[u] = max(f[u],siz[to]);
}
f[u] = max(f[u], allnode - siz[u]);
if(f[u] < f[root]) root = u;
}
void getdeep(int u,int fa,LL now) {
deep[++deep[]] = now*v[u]%mod;
id[deep[]] = u;
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(vis[to] || to == fa) continue;
getdeep(to,u,now*v[u]%mod);
}
}
void update(int u,int x,int y) {
int tmp = mp[inv[x*v[u]%mod]*K%mod];
if(!tmp) return ;
if(y > tmp) swap(y,tmp);
if(y < ansl || (y == ansl && tmp < ansr)) ansl = y, ansr = tmp;
} void work(int u){
vis[u] = ;
mp[] = u;
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(vis[to]) continue;
deep[] = ;
getdeep(to,u,);
for(int j = ; j <= deep[]; ++j) update(u,deep[j],id[j]);
for(int j = ; j <= deep[]; ++j) if(!mp[deep[j]] || mp[deep[j]] > id[j])mp[deep[j]] = id[j];
}
mp[] = ;
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(vis[to]) continue;
deep[] = ;
getdeep(to,u,);
for(int j = ; j <= deep[]; ++j) mp[deep[j]] = ;
}
for(int i = head[u]; i; i = e[i].next) {
int to = e[i].to;
if(vis[to]) continue;
root = ;
allnode = siz[to];
getroot(e[i].to,root);
work(root);
}
}
int main() {
inv[]=;
for(int i=;i<mod;i++){int a=mod/i,b=mod%i;inv[i]=(inv[b]*(-a)%mod+mod)%mod;}
while(~scanf("%d%I64d",&n,&K)) {
t = ;memset(head,,sizeof(head));
memset(vis,,sizeof(vis));
ansl = ansr = inf;
for(int i = ; i <= n; ++i) scanf("%I64d",&v[i]);
for(int i = ; i < n; ++i) {
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
f[]=inf;
allnode=n;root=;
getroot(,);
work(root);
if(ansl == inf) puts("No solution");else
printf("%d %d\n",ansl,ansr);
}
return ;
}
HDU 4812 D Tree 树分治+逆元处理的更多相关文章
- HDU 4812 D Tree 树分治
题意: 给出一棵树,每个节点上有个权值.要找到一对字典序最小的点对\((u, v)(u < v)\),使得路径\(u \to v\)上所有节点权值的乘积模\(10^6 + 3\)的值为\(k\) ...
- hdu 4812 D Tree(树的点分治)
D Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Total ...
- HDU - 4812 D Tree 点分治
http://acm.hdu.edu.cn/showproblem.php?pid=4812 题意:有一棵树,每个点有一个权值要求找最小的一对点,路径上的乘积mod1e6+3为k 题解:点分治,挨个把 ...
- HDU 4812 D Tree 树分区+逆+hash新位置
意甲冠军: 特定n点树 K 以下n号码是正确的点 以下n-1行给出了树的侧. 问: 所以,如果有在正确的道路点图的路径 % mod = K 如果输出路径的两端存在. 多条路径则输出字典序最小的一条. ...
- HDU 4812 D Tree
HDU 4812 思路: 点分治 先预处理好1e6 + 3以内到逆元 然后用map 映射以分治点为起点的链的值a 成他的下标 u 然后暴力跑出以分治点儿子为起点的链的值b,然后在map里查找inv[b ...
- 【BZOJ-1468】Tree 树分治
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1025 Solved: 534[Submit][Status][Discuss] ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- POJ 1741.Tree 树分治 树形dp 树上点对
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 24258 Accepted: 8062 Description ...
- poj 1744 tree 树分治
Tree Time Limit: 1000MS Memory Limit: 30000K Description Give a tree with n vertices,each ed ...
随机推荐
- selenium源码分析-webdriver(二)
最近比较空闲就仔细看了一下Selenium的源码,因为主要是使用WebDriver所以重点关注了一下WebDriver的工作原理.在前一篇blog里已经解释过了WebDriver与之前Selenium ...
- mysql开启binlog
mysql开启binlog,至于为什么要开启binlog,可以google下. ## 设置server_id,一般设置为IP server_id= ## 复制过滤:需要备份的数据库名,多个库以逗号分隔 ...
- 安装m2crypto报错swig error : Unrecognized option -builtin
M2Crypto 是最完整的为 Python 包装 OpenSSL 的 RSA,DSA,DH,EC,HMACs,消息摘要,对称密码算法(包括AES)的一个库工具.而自从 M2Crypto 升级到版本 ...
- SIP介绍
1.概述: SIP(Session Initiation Protocol,会话初始协议)是由IETF制定的多媒体通信协议.它是一个基于文本的应用层控制协议,用于创建.修改和释放一个或多个参与者的会话 ...
- ACM/ICPC 之 "嵌套"队列 -插队(POJ2259)
这里插队的意思就是排队时遇到熟人则插到其后,否则排到队尾.(这个习惯不太好)(题意) 题目要求我们模拟“插队模型”和队列的入队和出队完成此算法. 由于题目的输入输出很多,此题的查找操作(找到熟人)需要 ...
- MongoDB 3.0 新特性【转】
本文来自:http://www.open-open.com/lib/view/open1427078982824.html#_label3 更多信息见官网: http://docs.mongodb.o ...
- [Android] RelativeLayout, LinearLayout,FrameLayout
Android RelativeLayout 属性 // 相对于给定ID控件 android:layout_above 将该控件的底部置于给定ID的控件之上; android:layout_below ...
- python2.79安装
从官网下载最新的安装程序,基于windows的,也可以直接百度下载 点击安装,如果其他用户不需要python的话,可以使用第二个,不过我们一般都是单用户,所以没差 选择安装路径,可按默认路径安装,也可 ...
- codeforces 540B.School Marks 解题报告
题目链接:http://codeforces.com/problemset/problem/540/B 题目意思:给出 k 个test的成绩,要凑剩下的 n-k个test的成绩,使得最终的n个test ...
- core
http://blog.csdn.net/xiaoxiaoniaoer1/article/details/7740820 1.core文件的生成开关和大小限制--------------------- ...