传送门

题意:找路径积$\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 [点分治]的更多相关文章

  1. hdu 4812 DTree (点分治)

    D Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)Total S ...

  2. hdu 5909 Tree Cutting [树形DP fwt]

    hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...

  3. hdu 5830 FFT + cdq分治

    Shell Necklace Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  4. HDU 5044 Tree(树链剖分)

    HDU 5044 Tree field=problem&key=2014+ACM%2FICPC+Asia+Regional+Shanghai+Online&source=1&s ...

  5. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

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

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

  7. HDU - 4812 D Tree 点分治

    http://acm.hdu.edu.cn/showproblem.php?pid=4812 题意:有一棵树,每个点有一个权值要求找最小的一对点,路径上的乘积mod1e6+3为k 题解:点分治,挨个把 ...

  8. hdu 5909 Tree Cutting——点分治(树形DP转为序列DP)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治的话,每次要做一次树形DP:但时间应该是 siz*m2 的.可以用 FWT 变成 siz*ml ...

  9. hdu 5909 Tree Cutting —— 点分治

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治,每次的 rt 是必选的点: 考虑必须选根的一个连通块,可以DP,决策就是在每个子树中决定选不 ...

随机推荐

  1. C语言单向链表

    1,为什么要用到链表 数组作为存放同类数据的集合,给我们在程序设计时带来很多的方便,增加了灵活性.但数组也同样存在一些弊病.如数组的大小在定义时要事先规定,不能在程序中进行调整,这样一来,在程序设计中 ...

  2. Linux系统调优权威指南

    1.关闭SELINUX功能1.1 修改配置文件,使关闭SELINUX永久生效sed 's#SELINUX=enforcing#SELINUX=disables#g' /etc/selinux/conf ...

  3. python云算法

    http://www.runoob.com/python3/python3-basic-operators.html 本章节主要说明Python的运算符.举个简单的例子 4 +5 = 9 . 例子中, ...

  4. LockSupport理解

    一.背景 在看并发包源码的时候看见过LockSupport,今天恰巧看到LockSupport字眼,于是看下jdk1.7中的源码结构.想着它应该是运用多线程的锁工具的,到底似乎怎么实现的呢? 二.使用 ...

  5. git常见操作

    本地仓库关联远程仓库 新建本地目录scala git init 这样就新建了一个本地仓库 在远端如github上新建仓库scala 关联远程仓库 git remote add origin git@g ...

  6. spring定时任务执行两次 项目重复初始化 项目启动两次

    tomcat/config/server.xml中Host标签Context节点的问题 项目里quartz定时器总是被执行2次,通过打印发现原来项目被加载了两次,所以项目下的Listener被重复加载 ...

  7. 关于php存储cookie时path存放路径放的详细介绍

    以前在存储cookie时,没有用到path这个参数,最近开发中在存储cookie时,要用到path参数来决定存储的路径,结果一开始的时候一直取不到值,到最后详细看了一下path参数的介绍后,才顿悟.分 ...

  8. destoon 默认广告位代码

    <img src="http://www.testinstrument.cn/skin/default/jiurong/img/banner.png" alt="& ...

  9. asp.net -mvc框架复习(4)-ASP.NET MVC中的约定规则

    1.路由规则 using System;using System.Collections.Generic;using System.Linq;using System.Web;using System ...

  10. CCF系列之出现次数最多的数(201312-1)

    试题名称: 出现次数最多的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定n个正整数,找出它们中出现次数最多的数.如果这样的数有多个,请输出其中最小的一个.   输入格 ...