题意:

给定一棵 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. poj3050 Hopscotch

    思路: 水题. 实现: #include <iostream> #include <cstdio> #include <set> using namespace s ...

  2. reveal.js让程序员做ppt也享受快乐

    前言 程序员除了会写的一手漂亮的代码,也要求做出风格优雅的PPT,诸如向领导汇报工作.向小组成员反馈项目进展自己的工作等等.就本人而言,做ppt还要去找模板,还需要设计风格,内心是焦灼的.于是乎,我搜 ...

  3. 用RecyclerView做一个小清新的Gallery效果

    一.简介 RecyclerView现在已经是越来越强大,且不说已经被大家用到滚瓜烂熟的代替ListView的基础功能,现在RecyclerView还可以取代ViewPager实现Banner效果,当然 ...

  4. OpenGl之旅-—初识opengl

    昨天学习了如何使用codeblocks来编译运行一个opengl的项目.在创建一个新的opengl项目时他默认已经写了一个示例,今天我们就上面的例子进行下代码的剖析,以此来敲开opengl的神秘大门. ...

  5. mybatis 返回值

    转载: 在使用ibatis插入数据进数据库的时候,会用到一些sequence的数据,有些情况下,在插入完成之后还需要将sequence的值返回,然后才能进行下一步的操作.      使用ibatis的 ...

  6. C/C++ 各进制赋值、int/char转换、sscanf/sprintf、位操作运算

    一.各进制赋值 1.十六进制赋值 int i=0x12AD; int i=0X12AD; int i=0x12Ad; int i=0X12Ad; //以上都是十六进制,表示十进制173: 2.八进制赋 ...

  7. list map接口传递

    1.传参时可以设置为jsonArray的格式 JSONArray array = new JSONArray(); JSONObject json = new JSONObject(); json.p ...

  8. h5混编问题总结

    h5混编总结: 1.fragment 格式错误导致跳转混乱的问题:修改格式: 2.有缓存回退js不执行问题:未解决: 3.无缓存跨域回退白屏问题:解决跨域问题. 4.

  9. CAD参数绘制样条线(网页版)

    在CAD设计时,需要绘制样条线,用户可以设置样条线线重及颜色等属性. 主要用到函数说明: _DMxDrawX::PathLineTo 把路径下一个点移到指定位置.详细说明如下: 参数 说明 DOUBL ...

  10. VS2017 ATL创建ActiveX编程要点

    VS2017 ATL创建ActiveX控件编程要点: 一.创建vs项目需要安装器visual studio installer中: 安装 visual studio扩展开发中的 用于x86和x64的V ...