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的更多相关文章

  1. Solution -「AGC 029E」「AT 4504」Wandering TKHS

    \(\mathcal{Description}\)   Link.   给一棵 \(n\) 个点的树,从某个点出发,遍历时必须走到已经走过的连通块所邻接的编号最小的结点.求从每个点出发,走到 \(1\ ...

  2. [Agc029E]Wandering TKHS_树形dp_树上差分

    Wandering TKHS 题目链接:https://atcoder.jp/contests/agc029/tasks/agc029_e 数据范围:略. 题解: 好神啊 Orz司队 https:// ...

  3. 【AtCoder】AGC029(A-E)

    A - Irreversible operation 题解 把每个B后面的W个数累加起来即可 代码 #include <bits/stdc++.h> #define fi first #d ...

  4. f2fs解析(一)f2fs如何解决wandering tree

    wandering tree问题是log-structured 文件系统(LFS) 特有的一个问题,因为LFS的脏数据是追加更新的,所以如果一个数据块变脏了,那么那个数据块的直接索引块.间接索引块都会 ...

  5. hdu6229 Wandering Robots 2017沈阳区域赛M题 思维加map

    题目传送门 题目大意: 给出一张n*n的图,机器人在一秒钟内任一格子上都可以有五种操作,上下左右或者停顿,(不能出边界,不能碰到障碍物).题目给出k个障碍物,但保证没有障碍物的地方是强联通的,问经过无 ...

  6. 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 ...

  7. HDU 6229 - Wandering Robots - [概率题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6229 转载: https://blog.csdn.net/Anna__1997/article/det ...

  8. 【概率】【找规律】hdu6229 Wandering Robots

    题意:一个机器人在正方形迷宫的左上角,迷宫里有些格子有障碍物,每一步机器人会等概率地向能走的格子转移(包含自身).问你无限长的时间之后,机器人处于矩形对角线的右下方的概率. 无限长时间意味着,起点没有 ...

  9. HDU 6229 Wandering Robots(2017 沈阳区域赛 M题,结论)

    题目链接  HDU 6229 题意 在一个$N * N$的格子矩阵里,有一个机器人. 格子按照行和列标号,左上角的坐标为$(0, 0)$,右下角的坐标为$(N - 1, N - 1)$ 有一个机器人, ...

随机推荐

  1. storm-jdbc的使用

    最近项目组分配到研究storm-jdbc用法 发现网上关于insert和query方法挺多的,但是自定义方法很少.而且用法上也挺多缺陷.在此自己总结记录一下 JdbcInsertBolt 的核心代码 ...

  2. day18 8.jdbc中设置事务隔离级别

    设置数据库事务隔离级别特殊需求才有,后面很少用.因为数据库本身是事务隔离级别的,mysql的事务隔离级别是Repeatable read,可以解决脏读和不可重复读.不用设置,人家数据库是有事务隔离级别 ...

  3. shiro+jwt+springboot理解

    转自 https://www.cnblogs.com/fengli9998/p/6676783.html https://www.jianshu.com/p/0366a1675bb6 https:// ...

  4. Django项目:CRM(客户关系管理系统)--39--31PerfectCRM实现King_admin编辑多对多限制

    readonly_fields = ('qq', 'consultant','tags',) # 不可修改 # forms.py # ————————19PerfectCRM实现King_admin数 ...

  5. 【洛谷3295】[SCOI2016]萌萌哒

    传送门 倍增并查集. //Twenty #include<algorithm> #include<iostream> #include<cstdlib> #incl ...

  6. vw单位相关

    1.相对于视口的宽度.视口被均分为100单位的vw h1 { font-size: 8vw; } 如果视口的宽度是200mm,那么上述代码中h1元素的字号将为16mm,即(8x200)/100 2.相 ...

  7. Clash Credenz 2014 Wild Card Round题解

    A题 简单模拟. /************************************************************************* > File Name: ...

  8. MySQL下载安装详情教程(Windows)

    1.下载MySQL数据库可以访问官方网站:https://www.mysql.com/ 2.点击DOWNLOADS模块下的Community模块下的MySQL Community Server进行下载 ...

  9. Pull Request的过程、基于git做的协同开发、git常见的一些命令、git实现代码的review、git实现版本的管理、gitlab、GitHub上为开源项目贡献代码

    前言: Pull Request的流程 1.fork 首先是找到自己想要pull request的项目, 然后点击fork按钮,此时就会在你的仓库中多出来一个仓库,格式是:自己的账户名/想要pull ...

  10. 洛谷P2723 丑数 Humble Numbers [2017年 6月计划 数论07]

    P2723 丑数 Humble Numbers 题目背景 对于一给定的素数集合 S = {p1, p2, ..., pK},考虑一个正整数集合,该集合中任一元素的质因数全部属于S.这个正整数集合包括, ...