AGC029 E: Wandering TKHS
E: Wandering TKHS - AtCoder Grand Contest 029 | AtCoder
分类讨论好题(也不太算分类讨论)
方法:感受过程手玩,考虑能不能提前预算一些东西,或者递推,递归
也就是,找问题划分点
关注一个点x到根节点的最大值mx[x](包括自己)
因为最大值的父亲fa[mx[x]]的ans一定不会扩展mx[x]
所以求出mx[x]
对于mx[x]!=x情况
定义son[x],x的mx[x]往x方向走的第一个儿子
x一定会历经艰难扩展到mx,期间son[x]子树内,mx[*]=mx[x]的*都会被扩展。第一部分
走到了mx
之后,son[x]子树不会有任何扩展,
但是还可能会扩展一些mx除了son[x]的其他子树点y
如果y到根的次大值(最大值一定也是mx)是mx到根的次大值se[mx]的话,那么一定在次大值及之前会被扩展。第二部分
所以,次大值也关心。
然后就是ans[fa[mx]]了,之前已经算过,而且不会算重!第三部分
子树某个值出现次数
第一部分线段树合并
第二部分线段树合并,再减去son[x]子树的贡献
对于mx[x]==x情况
更好处理
直接变成上述情况的第二部分。mx子树内,se[*]=se[x]的个数
线段树合并。
代码:
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
namespace Modulo{
const int mod=;
int ad(int x,int y){return (x+y)>=mod?x+y-mod:x+y;}
void inc(int &x,int y){x=ad(x,y);}
int mul(int x,int y){return (ll)x*y%mod;}
void inc2(int &x,int y){x=mul(x,y);}
int qm(int x,int y=mod-){int ret=;while(y){if(y&) ret=mul(x,ret);x=mul(x,x);y>>=;}return ret;}
}
//using namespace Modulo;
namespace Miracle{
const int N=2e5+;
int n;
struct node{
int nxt,to;
}e[*N];
int hd[N],cnt;
void add(int x,int y){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
int se[N],mx[N];
int son[N];
int pa[N];
void dfs(int x,int fa){
se[x]=se[fa];
mx[x]=mx[fa];
if(x>mx[x]){
se[x]=mx[x];mx[x]=x;
}else se[x]=max(se[x],x);
if(mx[x]==mx[fa]){
if(mx[fa]==fa) son[x]=x;
else son[x]=son[fa];
}
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa) continue;
pa[y]=x;
dfs(y,x);
}
}
struct tr{
int ls,rs;
int cnt[];
}t[N*];
int tot;
int rt[N];
#define mid ((l+r)>>1)
void upda(int &x,int l,int r,int p,int c){
if(!x) x=++tot;
if(l==r){
t[x].cnt[c]++;return;
}
if(p<=mid) upda(t[x].ls,l,mid,p,c);
else upda(t[x].rs,mid+,r,p,c);
}
int merge(int x,int y,int l,int r){
if(!x||!y) return x+y;
if(l==r){
t[x].cnt[]=t[x].cnt[]+t[y].cnt[];
t[x].cnt[]=t[x].cnt[]+t[y].cnt[];
return x;
}
t[x].ls=merge(t[x].ls,t[y].ls,l,mid);
t[x].rs=merge(t[x].rs,t[y].rs,mid+,r);
return x;
}
void dfs2(int x,int fa){
upda(rt[x],,n,mx[x],);
upda(rt[x],,n,se[x],);
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa) continue;
dfs2(y,x);
rt[x]=merge(rt[x],rt[y],,n);
}
}
int query(int x,int l,int r,int p,int c){
if(!x) return ;
if(l==r) return t[x].cnt[c];
if(p<=mid) return query(t[x].ls,l,mid,p,c);
else return query(t[x].rs,mid+,r,p,c);
}
int ans[N];
void fin(int x,int fa){
if(x!=){
if(mx[x]!=x){
int A=query(rt[son[x]],,n,mx[x],),B=query(rt[mx[x]],,n,se[mx[x]],),C=-query(rt[son[x]],,n,se[mx[x]],),D=ans[pa[mx[x]]];
// cout<<" xx "<<x<<" : "<<A<<" "<<B<<" "<<C<<" "<<D<<endl;
ans[x]=A+B+C+D;
}else{
ans[x]=query(rt[x],,n,se[x],)+ans[fa];
}
}
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa) continue;
fin(y,x);
}
}
int main(){
rd(n);int x,y;
for(reg i=;i<n;++i){
rd(x);rd(y);
add(x,y);add(y,x);
}
dfs(,);
dfs2(,);
// prt(se,1,n);
// prt(mx,1,n);
// prt(son,1,n);
fin(,);
prt(ans,,n);
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
*/
mx的发现很关键,以mx位置为划分点,可以把问题分成若干部分处理,
由于fa[mx]不会再进入mx,还支持递归!
AGC029 E: Wandering TKHS的更多相关文章
- Solution -「AGC 029E」「AT 4504」Wandering TKHS
\(\mathcal{Description}\) Link. 给一棵 \(n\) 个点的树,从某个点出发,遍历时必须走到已经走过的连通块所邻接的编号最小的结点.求从每个点出发,走到 \(1\ ...
- [Agc029E]Wandering TKHS_树形dp_树上差分
Wandering TKHS 题目链接:https://atcoder.jp/contests/agc029/tasks/agc029_e 数据范围:略. 题解: 好神啊 Orz司队 https:// ...
- 【AtCoder】AGC029(A-E)
A - Irreversible operation 题解 把每个B后面的W个数累加起来即可 代码 #include <bits/stdc++.h> #define fi first #d ...
- f2fs解析(一)f2fs如何解决wandering tree
wandering tree问题是log-structured 文件系统(LFS) 特有的一个问题,因为LFS的脏数据是追加更新的,所以如果一个数据块变脏了,那么那个数据块的直接索引块.间接索引块都会 ...
- hdu6229 Wandering Robots 2017沈阳区域赛M题 思维加map
题目传送门 题目大意: 给出一张n*n的图,机器人在一秒钟内任一格子上都可以有五种操作,上下左右或者停顿,(不能出边界,不能碰到障碍物).题目给出k个障碍物,但保证没有障碍物的地方是强联通的,问经过无 ...
- Reading Famous blog to prevent me wasting time on blind wandering
I can`t help surfing the useless bbs and some other kind of SNS. The time I begin to do it, it costs ...
- HDU 6229 - Wandering Robots - [概率题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6229 转载: https://blog.csdn.net/Anna__1997/article/det ...
- 【概率】【找规律】hdu6229 Wandering Robots
题意:一个机器人在正方形迷宫的左上角,迷宫里有些格子有障碍物,每一步机器人会等概率地向能走的格子转移(包含自身).问你无限长的时间之后,机器人处于矩形对角线的右下方的概率. 无限长时间意味着,起点没有 ...
- HDU 6229 Wandering Robots(2017 沈阳区域赛 M题,结论)
题目链接 HDU 6229 题意 在一个$N * N$的格子矩阵里,有一个机器人. 格子按照行和列标号,左上角的坐标为$(0, 0)$,右下角的坐标为$(N - 1, N - 1)$ 有一个机器人, ...
随机推荐
- Java虚拟机系列(一)---Java内存划分
Java和C++之间有一堵由内存管理和垃圾收集技术所围成的“高墙”,墙外的人想进去,墙内的人却想出来. ------摘自<深入理解Java虚拟机> 作为一个Java程序员,因为虚拟机的好 ...
- express-generator简单使用
1.安装 npm install express npm install -g express-generator 全局安装.express-generator是一个node的自动化创建项目工具,类似 ...
- HBase 三维模型解析
总结下一直想写hbase的实践经验,在用hbase的过程中,我们都知道,rowkey设计的好坏,是我们能最大发挥hbase的架构优势,也是我们是否正确理解hbase的一个关键点.闲话少说,进入正题. ...
- 非常好理解的KNN算法示例
参考链接:https://www.joinquant.com/post/2227?f=study&m=math:一只兔子帮你理解KNN https://www.joinquant.com/po ...
- LUOGU P4171 [JSOI2010]满汉全席
传送门 解题思路 2-SAT 裸题. 代码 #include<iostream> #include<cstdio> #include<cstring> #inclu ...
- jeecms9自定义标签以及使用新创建的数据库表
转载 https://blog.csdn.net/nice_meng/article/details/89179089 本系统使用的是jeecmsv9版本,收集网上知识后,进行个人汇总 首先,自己创建 ...
- python基础--线程、进程
并发编程: 操作系统:(基于单核研究) 多道技术: 1.空间上的复用 多个程序共用一个计算机 2.时间上的复用 切换+保存状态 例如:洗衣 烧水 做饭 切换: 1.程序遇到IO操作系统会立刻剥夺着CP ...
- LINNX查看当前登录的用户
W w命令主要是查看当前登录的用户,这个命令相对来说比较简单.我们来看一下截图. 在上面这个截图里面呢,第一列user,代表登录的用户,第二列,tty代表用户登录的终端号,因为在linux中并不是只有 ...
- git命令移动文件夹到另一文件夹
- django中的路由规则
项目的目录结构 外层的firstysite目录与Django无关,只是你项目的容器,可以任意重命名. #其中settings.py是django的总配置文件,即项目的总管家#urls.py,则是项目的 ...