【HDOJ4812】D Tree(点分治)
题意:
给定一棵 n 个点的树,每个点有权值 Vi
问是否存在一条路径使得路径上所有点的权值乘积 mod(10^6 + 3) 为 K
输出路径的首尾标号,若有多解,输出字典序最小的解
对于100%的数据,有1≤n≤10^5,0≤K≤10^6+2,1≤vi ≤10^6+2
思路:RYZ作业
预处理逆元
哈希路径权值乘积的模数,保存编号用来查询
const mo=;
var head,vet,next,len,flag,son:array[..]of longint;
f:array[..]of longint;
dis,a:array[..]of int64;
q:array[..,..]of longint;
exf:array[..mo]of int64;
hash:array[..mo]of longint;
n,m,i,j,tot,x,y,z,ans1,ans2,sum,root,top,k:longint; procedure add(a,b:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
head[a]:=tot;
end; function max(x,y:longint):longint;
begin
if x>y then exit(x);
exit(y);
end; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; function getroot(u,fa:longint):longint;
var e,v:longint;
begin
son[u]:=; f[u]:=;
e:=head[u];
while e<> do
begin
v:=vet[e];
if (v<>fa)and(flag[v]=) then
begin
getroot(v,u);
son[u]:=son[u]+son[v];
f[u]:=max(f[u],son[v]);
end;
e:=next[e];
end;
f[u]:=max(f[u],sum-f[u]);
if f[u]<f[root] then root:=u;
end; procedure dfs(u,fa:longint);
var e,v:longint;
begin
inc(top); q[top,]:=dis[u]; q[top,]:=u;
e:=head[u];
while e<> do
begin
v:=vet[e];
if (v<>fa)and(flag[v]=) then
begin
dis[v]:=dis[u]*a[v] mod mo;
dfs(v,u);
end;
e:=next[e];
end;
end; procedure cmp(x,id:longint);
var y:longint;
begin
x:=exf[x]*k mod mo;
y:=hash[x];
if y= then exit;
if y>id then swap(y,id);
if (y<ans1)or((y=ans1)and(id<ans2)) then
begin
ans1:=y; ans2:=id;
end;
end; procedure solve(u:longint);
var e,v,i,now:longint;
begin
flag[u]:=; hash[a[u]]:=u;
e:=head[u];
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
top:=; dis[v]:=a[v];
dfs(v,u);
for i:= to top do cmp(q[i,],q[i,]); //对于每一个子树,因为不能重复计算u这个根结点,分别计算子树内结果,后面再用加上根结点的答案更新
top:=; dis[v]:=a[u]*a[v] mod mo;
dfs(v,u);
for i:= to top do
begin
now:=hash[q[i,]];
if (now=)or(q[i,]<now) then hash[q[i,]]:=q[i,]; //用子树中的路径加上根结点,更新经过根结点的答案
end;
end;
e:=next[e];
end;
hash[a[u]]:=;
e:=head[u];
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
top:=; dis[v]:=a[u]*a[v] mod mo;
dfs(v,u);
for i:= to top do hash[q[i,]]:=; //清空所有信息
end;
e:=next[e];
end;
e:=head[u];
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
root:=; sum:=son[v];
getroot(v,);
solve(root);
end;
e:=next[e];
end;
end; begin
assign(input,'hdoj4812.in'); reset(input);
assign(output,'hdoj4812.out'); rewrite(output);
exf[]:=; exf[]:=;
for i:= to do exf[i]:=exf[mo mod i]*(mo-mo div i) mod mo;
while not eof do
begin
// fillchar(head,sizeof(head),);
//fillchar(flag,sizeof(flag),);
for i:= to n do
begin
head[i]:=; flag[i]:=;
end;
tot:=; ans1:=maxlongint; ans2:=maxlongint;
read(n,k);
if n= then break;
for i:= to n do read(a[i]);
for i:= to n- do
begin
read(x,y);
add(x,y);
add(y,x);
end;
root:=; sum:=n; f[]:=n+;
getroot(,);
solve(root);
if ans1=maxlongint then writeln('No solution')
else writeln(ans1,' ',ans2);
end;
close(input);
close(output);
end.
【HDOJ4812】D Tree(点分治)的更多相关文章
- hdoj4812 D Tree(点分治)
题目链接:https://vjudge.net/problem/HDU-4812 题意:给定一颗带点权的树,求是否存在一条路经的上点的权值积取模后等于k,如果存在多组点对,输出字典序最小的. 思路: ...
- 【BZOJ-1468】Tree 树分治
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1025 Solved: 534[Submit][Status][Discuss] ...
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- [bzoj 1468][poj 1741]Tree [点分治]
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
- 【CF434E】Furukawa Nagisa's Tree 点分治
[CF434E]Furukawa Nagisa's Tree 题意:一棵n个点的树,点有点权.定义$G(a,b)$表示:我们将树上从a走到b经过的点都拿出来,设这些点的点权分别为$z_0,z_1... ...
- POJ 1741 Tree(点分治点对<=k)
Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...
- 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 ...
- CF1039D You Are Given a Tree 根号分治,贪心
CF1039D You Are Given a Tree LG传送门 根号分治好题. 这题可以整体二分,但我太菜了,不会. 根号分治怎么考虑呢?先想想\(n^2\)暴力吧.对于每一个要求的\(k\), ...
随机推荐
- Snort里如何将读取的包记录存到二进制tcpdump文件下(图文详解)
不多说,直接上干货! 如果网络速度很快,或者想使日志更加紧凑以便以后的分析,那么应该使用二进制的日志文件格式.如tcpdump格式或者pcap格式. 这里,我们不需指定本地网络了,因为所以的东西都被 ...
- selenium通过autoit实现上传和下载
autoit安装目录如下: AutoIt Windows Info 用于帮助我们识Windows控件信息. Compile Script to.exe 用于将AutoIt生成 exe 执行文件. ...
- [BZOJ2456]mode 其它
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2456 这道题有着神奇的内存限制1MB也就是说我们是没办法把读入的数字存下来的. 由于答案求 ...
- No rule to make target ...
在编译一个Android上的jni的时候出现了如下的问题 make[3]: *** No rule to make target `/home/zhang/android1/src/androidpk ...
- R in action读书笔记(7)-第七章:基本统计分析(下)
7.3相关 相关系数可以用来描述定量变量之间的关系.相关系数的符号(±)表明关系的方向(正相关或负相关),其值的大小表示关系的强弱程度(完全不相关时为0,完全相关时为1).除了基础安装以外,我们还将使 ...
- 用 dojo/request/script 玩垮域
dojo/request/script 可以用于向服务器发送跨域请求,如JSONP等.但单看官方文档有点不容易理解,特将体会记录. require(["dojo/request/script ...
- C# 方法 虚方法的调用浅谈 引用kdalan的博文
我们在面试中经常碰到有关多态的问题,之前我也一直被此类问题所困扰,闹不清到底执行哪个方法. 先给出一道简单的面试题,大家猜猜看,输出是? public class A { ...
- win8怎么打开或关闭快速启动(进入BIOS前的设置)
win8系统之后,系统添加了快速启动功能,这让Windows的启动速度快了不少.但是,任何事物有利有弊,相信不少人在进入BIOS或者重装系统时遇到了麻烦.接下来我们看看在win8及以上版本怎么打开或关 ...
- MAC加域重复跳出---"talagent"想使用“本地项目” 的钥匙串
很简单的解决办法,就是把以前的钥匙串给删掉就好 (重要提示:这个方法,以前所有程序自动记录密码都会丢掉,safari的自动填充,QQ自动登录,imessages 的等等) 1.打开Finder -&g ...
- cf536c——思路题
题目 题目:Lunar New Year and Number Division 题目大意:给定一个数字序列,可以任意分组(可调整顺序),但每组至少两个,求每组内数字和的平方的最小值 思路 首先,易证 ...