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 ...
随机推荐
- POJ 2570(floyd)
http://poj.org/problem?id=2570 题意:在海底有一些网络节点.每个节点之间都是通过光缆相连接的.不过这些光缆可能是不同公司的. 现在某个公司想从a点发送消息到b点,问哪个公 ...
- iOS GCD 必读推荐,有关于单例使用问题
链接如下:http://www.cocoachina.com/swift/20150129/11057.html 以前只注意使用dispatch_once达到创建单例对象时的线程安全,读了下边这篇文章 ...
- selenium处理rich text(富文本框)
WordPress 的 rich text 采用js,先让selenium切换到iframe中 driver.switchTo().frame("content_ifr"); 然 ...
- perl Can't use string Cxxx) as a symbol ref while "strict refs" in use at XXXX.pl错误
今天写脚本遇到Can't use string ("bond2 Link encap:InfiniBand ") as a symbol ref while "s ...
- MySQL表字段长度的限制
在MySQL建表时,遇到一个奇怪的现象: root::>CREATE TABLE tb_test ( ) NOT NULL, ) DEFAULT NULL, ) DEFAULT NULL, ) ...
- json格式
$.post('text.action',{....},function(datas){ var name=datas.data[0].name; }); 如果是多个还可以用循环获取.$.post(' ...
- java入门 第三季2
java中的字符串 java中的常用类
- java 入门 第二季4
1. 多态 继承是多态的实现基础 引用的多态 父类的引用可以指向本类的对象 父类的引用可以指向子类的对象 方法的多态 创建本类对象时,调用本类方法 2种是调用子类的方法或继承的方法 子类中添加独有的方 ...
- 【leetcode】Remove Duplicates from Sorted List II (middle)
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numb ...
- autolayout autoresizing
WWDC 2012 Session笔记——202, 228, 232 AutoLayout(自动布局)入门 这是博主的WWDC2012笔记系列中的一篇,完整的笔记列表可以参看这里.如果您是首次来到本站 ...