【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\), ...
随机推荐
- SQL快速备份
ALTER PROCEDURE [dbo].[usp_Backup_DataBase] ( @BackupDataBaseName VARCHAR(128) )AS BE ...
- pandas之groupby分组与pivot_table透视表
zhuanzi: https://blog.csdn.net/qq_33689414/article/details/78973267 pandas之groupby分组与pivot_table透视表 ...
- [小记]Android缓存问题
今天晚上,产品经理打电话说我们的Android App除了问题,问题很简单就是一个缓存问题,由于这个程序是前同事写的,我也只能呵呵一笑,有些事你就得扛.还是回到正题吧,这个缓存问题,实在有点奇葩,所以 ...
- ASP.Net TextBox只读时不能通过后台赋值取值
给页面的TextBox设置ReadOnly="True"时,在后台代码中不能赋值取值,下边几种方法可以避免: 1.不设置ReadOnly,设置onfocus=this.blur() ...
- bat获取注册表值
@echo off Setlocal enabledelayedexpansion for /f "skip=2 delims=: tokens=1,*" %%i in ('reg ...
- leetcode_486. Predict the Winner
https://leetcode.com/problems/predict-the-winner/ 题目描述:给定一个非负的积分数组,玩家1可以从数组两端任取一个积分,接着玩家2执行同样的操作,直至积 ...
- CLUSTER - 根据一个索引对某个表集簇
SYNOPSIS CLUSTER indexname ON tablename CLUSTER tablename CLUSTER DESCRIPTION 描述 CLUSTER 指示PostgreSQ ...
- 进程的互斥运行:CreateMutex函数实现只运行一个程序实例
HANDLE hMutex=CreateMutex(NULL,TRUE,"HDZBUkeyDoctorTool"); if(hMutex) { if(ERROR_ALREADY_E ...
- 【原】简单shell练习(三)
1.软链 linux下的软链接类似于windows下的快捷方式 # ln -s /home/gamestat /gamestat ln -s a b 中的 a 就是源文件(已经存在的文件),b是链 ...
- ionic3 ion-slides遇坑
不想吐槽 ionic-slides 的组件,是个巨坑...切换页面以后再返回当前页面, 不能自动播放,网上的解决方案都是没用的(亲测,后台获取的数据) ... 不信邪的宝宝们可以去试试..建议换 ...