HDU D Tree [点分治]
题意:找路径积$\mod 1e6+3 = k$的字典序最小点对
作为一个点分治蒟蒻,写这道题花了两节课....
显然只要开一个桶$c[i]$记录当前路径积为$i$的最小点
然后处理一个子树时一个个子树遍历更新答案再更新$c$就行了
最后再把$c$复原
可以用一个栈记下更改过的$c$,但貌似比在遍历一遍树更慢?
然后注意更新和复原$c[w[u]]$
好了回教室上数学课啦
#pragma comment(linker,"/STACK:102400000,102400000")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+,M=1e6+,P=1e6+,INF=1e9;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n;ll k,w[N];
struct edge{
int v,ne;
}e[N<<];
int h[N],cnt;
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
cnt++;
e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
}
int inv[M];
void iniInv(){
inv[]=;
for(int i=;i<P;i++)
inv[i]=(ll)(P-P/i)*inv[P%i]%P;
} int size[N],f[N],vis[N],root,allSize;
void dfsRt(int u,int fa){
size[u]=;f[u]=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(vis[v]||v==fa) continue;
dfsRt(v,u);
size[u]+=size[v];
f[u]=max(f[u],size[v]);
}
f[u]=max(f[u],allSize-size[u]);
if(f[u]<f[root]) root=u;
}
int c[M],ans[];
int st[N],top;
void dfsDee(int u,int fa,int now){
if(!c[now]) c[now]=u;//,st[++top]=now;
else c[now]=min(c[now],u);
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(!vis[v]&&v!=fa) dfsDee(v,u,now*w[v]%P);
}
}
void dfsAns(int u,int fa,int now){
int x=c[k*inv[now]%P],y=u;
if(x){
if(x>y) swap(x,y);
if(x<ans[]||(x==ans[]&&y<ans[])) ans[]=x,ans[]=y;
}
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(!vis[v]&&v!=fa) dfsAns(v,u,now*w[v]%P);
}
}
void dfsRec(int u,int fa,int now){
c[now]=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(!vis[v]&&v!=fa) dfsRec(v,u,now*w[v]%P);
}
}
void dfsSol(int u){
vis[u]=;
c[w[u]]=u;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(!vis[v]){
dfsAns(v,u,w[v]);
dfsDee(v,u,w[u]*w[v]%P);
}
}
//while(top) c[st[top]]=0,top--;
for(int i=h[u];i;i=e[i].ne) if(!vis[e[i].v]) dfsRec(e[i].v,u,w[u]*w[e[i].v]%P);
c[w[u]]=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(!vis[v]){
root=;allSize=size[v];
dfsRt(v,);
dfsSol(root);
}
}
}
int main(){
freopen("in","r",stdin);
iniInv();
while(scanf("%d%lld",&n,&k)!=EOF){
memset(vis,,sizeof(vis));
cnt=;memset(h,,sizeof(h));
memset(c,,sizeof(c));
for(int i=;i<=n;i++) w[i]=read();
for(int i=;i<=n-;i++) ins(read(),read());
ans[]=ans[]=INF;
f[]=INF;
root=;allSize=n;
dfsRt(,);
dfsSol(root);
if(ans[]!=INF) printf("%d %d\n",ans[],ans[]);
else puts("No solution");
}
}
HDU D Tree [点分治]的更多相关文章
- hdu 4812 DTree (点分治)
D Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total S ...
- hdu 5909 Tree Cutting [树形DP fwt]
hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...
- hdu 5830 FFT + cdq分治
Shell Necklace Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- HDU 5044 Tree(树链剖分)
HDU 5044 Tree field=problem&key=2014+ACM%2FICPC+Asia+Regional+Shanghai+Online&source=1&s ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- HDU - 4812 D Tree 点分治
http://acm.hdu.edu.cn/showproblem.php?pid=4812 题意:有一棵树,每个点有一个权值要求找最小的一对点,路径上的乘积mod1e6+3为k 题解:点分治,挨个把 ...
- hdu 5909 Tree Cutting——点分治(树形DP转为序列DP)
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治的话,每次要做一次树形DP:但时间应该是 siz*m2 的.可以用 FWT 变成 siz*ml ...
- hdu 5909 Tree Cutting —— 点分治
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治,每次的 rt 是必选的点: 考虑必须选根的一个连通块,可以DP,决策就是在每个子树中决定选不 ...
随机推荐
- net+Oracle开发过程中遇到的小问题
最新的项目开始使用Oracle后,5个月之间遇到一些在SqlServer中没有遇到的问题,这里记录并贴上一些常用的解决办法. Oracle相关 一.数据库不同版本还原: 刚开始我们一直使用Oracle ...
- Redis介绍及Jedis测试
1.Redis简介 Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes ...
- 重新学习一次javascript;
每次有项目的时候,总觉得自己什么都不会做,然后做的时候又很简单,一会就做完了,啪啪打脸: 每次别人问的时候,我知道怎么做,但是不知道具体原理,觉得瞬间low了: 想要好好的吧基础掌握一下: 这几天空闲 ...
- 总结过滤器,监听器,servlet的异同点,已经执行顺序。
1.过滤器 Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码.做一些业务逻辑判断等.其工作原理是,只要你在web.xml ...
- c++(八皇后)
八皇后是一道很具典型性的题目.它的基本要求是这样的:在一个8*8的矩阵上面放置8个物体,一个矩阵点只允许放置一个物体,任意两个点不能在一行上,也不能在一列上,不能在一条左斜线上,当然也不能在一条右斜线 ...
- Generator函数异步应用
转载请注明出处: Generator函数异步应用 上一篇文章详细的介绍了Generator函数的语法,这篇文章来说一下如何使用Generator函数来实现异步编程. 或许用Generator函数来实现 ...
- 【端-iOS】给iOS开发入门者编码的一点建议
规范编码可以提高代码的可读性,降低维护成本.作为一个程序员,要对自己写的代码负责,虽然bug无可避免,但是写代码时最基本的编码规则还是应该遵守的,否则不是坑自己就是坑别人,因为代码肯定是要维护的. 下 ...
- tp5 点击刷新验证码
<form action="<{:url('index/index/login')}>" method="post" name="f ...
- [拾 得] zip gzip bzip2 & tar 压缩/打包 四大金刚
坚持知识分享,该文章由Alopex编著, 转载请注明源地址: http://www.cnblogs.com/alopex/ 索引: 介绍压缩和打包 gzip bzip2 zip 的基本使用 gz ...
- Java数据持久层框架 MyBatis之API学习九(SQL语句构建器详解)
对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...