题意:

给定一棵 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(点分治)的更多相关文章

  1. hdoj4812 D Tree(点分治)

    题目链接:https://vjudge.net/problem/HDU-4812 题意:给定一颗带点权的树,求是否存在一条路经的上点的权值积取模后等于k,如果存在多组点对,输出字典序最小的. 思路: ...

  2. 【BZOJ-1468】Tree 树分治

    1468: Tree Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 534[Submit][Status][Discuss] ...

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

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

  4. POJ 1741 Tree 树分治

    Tree     Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...

  5. [bzoj 1468][poj 1741]Tree [点分治]

    Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...

  6. 【CF434E】Furukawa Nagisa's Tree 点分治

    [CF434E]Furukawa Nagisa's Tree 题意:一棵n个点的树,点有点权.定义$G(a,b)$表示:我们将树上从a走到b经过的点都拿出来,设这些点的点权分别为$z_0,z_1... ...

  7. POJ 1741 Tree(点分治点对<=k)

    Description Give a tree with n vertices,each edge has a length(positive integer less than 1001). Def ...

  8. POJ 1741.Tree 树分治 树形dp 树上点对

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 24258   Accepted: 8062 Description ...

  9. poj 1744 tree 树分治

    Tree Time Limit: 1000MS   Memory Limit: 30000K       Description Give a tree with n vertices,each ed ...

  10. CF1039D You Are Given a Tree 根号分治,贪心

    CF1039D You Are Given a Tree LG传送门 根号分治好题. 这题可以整体二分,但我太菜了,不会. 根号分治怎么考虑呢?先想想\(n^2\)暴力吧.对于每一个要求的\(k\), ...

随机推荐

  1. 转 【TTS】AIX平台数据库迁移到Linux--基于RMAN(真实环境)

    [TTS]AIX平台数据库迁移到Linux--基于RMAN(真实环境) http://www.cnblogs.com/lhrbest/articles/5186933.html 各位技术爱好者,看完本 ...

  2. Ref 和 Out 区别(演练代码)

    一.代码 今天就总结Ref和Out 的总结,这东西,也是经常面试过程中,笔试经常考的,比如:请简述Ref和Out 的区别,或者通过一段代码让你计算这过程的结果.... Out代码实例::: stati ...

  3. 构建微服务开发环境2————安装IntelliJ IDEA

    [内容指引] 下载IntelliJ IDEA安装包: Mac版IDEA安装: Windows版IDEA按装. 一.下载IntelliJ IDEA安装包 访问官方网址:https://www.jetbr ...

  4. 2017团体程序设计天梯赛大区赛 L3-3 球队“食物链”

    思路: 状压dp. 实现: #include <iostream> #include <cstdio> #include <cstring> using names ...

  5. 用js的eval函数模拟Web API中的onclick事件

    在检查组内小伙伴提交的tabToggler插件的js代码时,发现了onclick的如下用法: el.onclick = function(){ //按钮样式切换 for(var i=0;i<ob ...

  6. 架构师细说 NGINX 的配置及优化

    最近感觉很多东西在运用到一定的程度之后,会发现原来是自己了解到的不够.一方面限于实际运用到的不多,一方面可能是因为一开始没有进行全面认识.遂这里搜集整理了一番NGINX. 一.nginx启动和关闭 c ...

  7. iOS Programming Dynamic Type 2

    iOS Programming Dynamic Type  2       You will need to update two parts of this view controller for ...

  8. 关于Qt模态框总汇

    转载请注明出处:http://www.cnblogs.com/dachen408/p/7285710.html 父窗体为QMainWindow: 当子窗体为: 1.QWidget,需要设置 this- ...

  9. IE和DOM事件流、普通事件和绑定事件的区别

    IE和DOM事件流的区别 IE采用冒泡型事件 Netscape(网络信息浏览器)使用捕获型事件 DOM使用先捕获后冒泡型事件 示例: <body> <div> <butt ...

  10. 程序员容易忽略的SQL Server错误集锦

    1.大小写 大写T-SQL 语言的所有关键字都使用大写,规范要求. 2.使用“;” 使用“;”作为 Transact-SQL 语句终止符.虽然分号不是必需的,但使用它是一种好的习惯,对于合并操作MER ...