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 ...
随机推荐
- hdu 5442 (ACM-ICPC2015长春网络赛F题)
题意:给出一个字符串,长度是2*10^4.将它首尾相接形成环,并在环上找一个起始点顺时针或逆时针走一圈,求字典序最大的走法,如果有多个答案则找起始点最小的,若起始点也相同则选择顺时针. 分析:后缀数组 ...
- Sql Server事务简单用法
var conStr = "server=localhost;database=Data;user=sa;pwd=123456"; using (var connection = ...
- Mysql 基础3
1. 逗号是个好东西2.对于多条件查询 和范围查询 的灵活运用(and 和or 的灵活运用)in 用的时候注意 补充select * from car where name like '%奥迪%' a ...
- 从API请求数据的方法(主要适用于tp5)
// 从api获取数据,$data是一个数组,默认为空,请求数据的方法可以通用,但是其它说明只适用于tp5 function postData($url,$data=''){ $ch = curl_i ...
- 【processing】小代码
今天无意间发现的processing 很有兴趣 实现很简洁 void setup(){ } void draw(){ background(); && mouseY > heig ...
- UICollectionView cellForItemAtIndexPath 方法不走
在storyboard 中 UICollectionView cellForItemAtIndexPath not called 被坑了好久,各种问题点查找,终于解决了 解决办法: self.auto ...
- sqlplus 设置
set heading offset line 40001.设置页面显示总行数show pagesize; //首先查看目前的pagesize,默认是14set pagesize 100; //将pa ...
- IOS管理文件和目录NSFileManager
1.常见的NSFileManager文件方法 -(NSData *)contentsAtPath:path //从一个文件读取数据 -(BOOL)createFileAtPath: path cont ...
- java ---线程wait/notify/sleep/yield/join
一.线程的状态 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态). New:新建状态,当线 ...
- 字符识别(模板匹配&BP神经网络训练)
http://blog.csdn.net/zhang11wu4/article/details/7585632