【树链剖分 ODT】cf1137F. Matches Are Not a Child's Play
孔爷的杂题系列;LCT清新题/ODT模板题
题目大意
定义一颗无根树的燃烧序列为:每次选取编号最小的叶子节点形成的序列。
要求支持操作:查询一个点$u$在燃烧序列中的排名;将一个点的编号变成最大
$n \le 200000$
题目分析
首先初始的燃烧序列容易构造,那么考虑进行一次up操作对序列会产生什么影响。
这里对$3$进行一次$up$,得到下图。
容易发现,记上一个版本序列最后一个元素为$las$,进行$up\,\,\,x$相当于是把路径$(las,x)$的答案变成从$las$到$x$的等差数列。因为$x$被$up$之后,这条路径只能从另一端的$las$走过来。
等差数列用线段树容易维护,这里讲一种ODT维护的方式:将路径$(las,x)$染为一种新颜色$c$,查询答案就是$1..c-1$颜色种类数+$dis(las,x)+1$.
那么就是一道难得的ODT+树剖模板题了。
关于下面132行的细节处理:写成root[i-1]=root[i]=u是因为对于初始序列,查询时候要保持dist(u, root[c-1])=0;但是对于之后修改的询问root[n]应该为n。
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ; struct node
{
int l,r,val;
node(int a=, int b=, int c=):l(a),r(b),val(c) {}
bool operator < (node a) const
{
return l < a.l;
}
};
struct point
{
int fa,son,top,tot;
}a[maxn];
char opt[];
int n,m,tim,lst,chain[maxn],chTot,root[maxn<<];
int edgeTot,head[maxn],nxt[maxm],edges[maxm],deg[maxn],dep[maxn];
std::set<node> s[maxn];
std::priority_queue<int, std::vector<int>, std::greater<int> > q;
typedef std::set<node>::iterator itr;
namespace BIT
{
int f[maxn<<];
void add(int x, int c){for (x+=; x<=n+m+; x+=x&-x) f[x] += c;}
int query(int x)
{
int ret = ;
for (x+=; x; x-=x&-x) ret += f[x];
return ret;
}
}; int read()
{
char ch = getchar();
int num = , fl = ;
for (; !isdigit(ch); ch=getchar())
if (ch=='-') fl = -;
for (; isdigit(ch); ch=getchar())
num = (num<<)+(num<<)+ch-;
return num*fl;
}
void addedge(int u, int v)
{
++deg[u], ++deg[v];
edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void dfs1(int x, int fa)
{
a[x].fa = fa, a[x].tot = ;
a[x].son = a[x].top = -, dep[x] = dep[fa]+;
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i];
if (v==fa) continue;
dfs1(v, x), a[x].tot += a[v].tot;
if (a[x].son==-||a[a[x].son].tot < a[v].tot) a[x].son = v;
}
}
void dfs2(int x, int top)
{
if (x==top) s[x].insert(node(n+, n+, ));
chain[x] = ++chTot, a[x].top = top;
if (a[x].son==-) return;
dfs2(a[x].son, top);
for (int i=head[x]; i!=-; i=nxt[i])
if (edges[i]!=a[x].fa&&edges[i]!=a[x].son)
dfs2(edges[i], edges[i]);
}
int Lca(int u, int v)
{
while (a[u].top!=a[v].top)
{
if (dep[a[u].top] > dep[a[v].top]) std::swap(u, v);
v = a[a[v].top].fa;
}
if (dep[u] > dep[v]) std::swap(u, v);
return u;
}
int dist(int u, int v)
{
int anc = Lca(u, v);
return dep[u]+dep[v]-(dep[anc]<<);
}
itr split(int i, int pos)
{
itr loc = s[i].lower_bound(node(pos));
if (loc!=s[i].end()&&loc->l==pos) return loc;
int l = (--loc)->l, r = loc->r, val = loc->val;
s[i].erase(loc), s[i].insert(node(l, pos-, val));
return s[i].insert(node(pos, r, val)).first;
}
void insert(int i, int l, int r, int c)
{
itr rpos = split(i, r+), lpos = split(i, l);
for (itr it=lpos; it!=rpos; ++it)
BIT::add(it->val, -(it->r-it->l+)); //遍历清除历史颜色
s[i].erase(lpos, rpos);
BIT::add(c, r-l+);
s[i].insert(node(l, r, c));
}
void chainModify(int u, int v)
{
while (a[u].top!=a[v].top)
{
if (dep[a[u].top] > dep[a[v].top]) std::swap(u, v);
insert(a[v].top, chain[a[v].top], chain[v], tim);
v = a[a[v].top].fa;
}
if (dep[u] > dep[v]) std::swap(u, v);
insert(a[u].top, chain[u], chain[v], tim);
}
int query(int u)
{
int c = split(a[u].top, chain[u])->val;
return BIT::query(c-)+dist(u, root[c-])+; //查询答案 root[c-1]是指上一个历史版本的最后一个元素las
}
int main()
{
memset(head, -, sizeof head);
n = read(), m = read();
for (int i=; i<n; i++) addedge(read(), read());
dfs1(, ), dfs2(, );
for (int i=; i<=n; i++)
if (deg[i]==) q.push(i);
for (int i=,u; i<=n; i++)
{
root[i-] = root[i] = u = q.top(), q.pop(); //见上解释
BIT::add(i, ), deg[u] = ;
s[a[u].top].insert(node(chain[u], chain[u], ++tim));
for (int i=head[u]; i!=-; i=nxt[i])
if ((--deg[edges[i]])==) q.push(edges[i]);
}
for (int i=; i<=m; i++)
{
scanf("%s",opt);
if (opt[]=='u'){
int v = read();
root[++tim] = v;
chainModify(v, root[tim-]);
}else if (opt[]=='w') printf("%d\n",query(read()));
else{
int u = read(), v = read();
printf("%d\n",(query(u) < query(v))?u:v);
}
}
return ;
}
END
【树链剖分 ODT】cf1137F. Matches Are Not a Child's Play的更多相关文章
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)
题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...
- 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)
题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...
- 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)
题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...
- bzoj2243树链剖分+染色段数
终于做了一道不是一眼出思路的代码题(⊙o⊙) 之前没有接触过这种关于染色段数的题目(其实上课好像讲过),于是百度了一下(现在思维能力好弱) 实际上每一段有用的信息就是总共有几段和两段各是什么颜色,在开 ...
- bzoj3631树链剖分
虽然是水题1A的感觉太爽了O(∩_∩)O~ 题意相当于n-1次树上路径上每个点权值+1,最后问每个点的权值 本来想写线段树,写好了change打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...
- BZOJ 3531: [Sdoi2014]旅行 [树链剖分]
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1685 Solved: 751[Submit][Status] ...
随机推荐
- [转]jQuery为控件添加水印文字
本文转自:http://www.cnblogs.com/gzh4455/archive/2011/09/29/2195418.html jQuery扩展: jquery.tinywatermark-3 ...
- PV、UV、VV,CV的含义
其中VV和CV是播放类指标,PV和UV是浏览类指标. 1. 播放类指标 VV(Video View,播放数),是指在一个统计周期内,视频被打开的次数之和. CV(Connect Views,内容播放数 ...
- pat1048. Find Coins (25)
1048. Find Coins (25) 时间限制 50 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Eva loves t ...
- C# 十进制与二进制、十六进制、八进制之间的转换
1.十进制 转 二进制 将十进制数不断地除2,将所有余数倒叙填写,即可得到所需二进制数据. public static string DecimalToBinary(int vDecimal) { / ...
- IIS设置问题
1.解决IIS7.5中部署WCF时,访问.svc文件的404错误问题 如果你直接在IIS 7中配置WCF,访问.svc文件时会出现404错误.解决方法,以管理员身份进入命令行模式,运行:" ...
- maven课程 项目管理利器-maven 3-3 maven中的坐标和仓库
本节主要讲了两大方面: 1 maven坐标 1.0 构件定义 任何依赖,插件,项目构建输出 都称之为构件. 1.1 maven坐标概念 groupid 公司或组织的域名倒序+当前项目名称 artif ...
- 在CentOS上配置redis服务
#!/bin/sh # # redis Startup script for Redis Server # # chkconfig: - 80 12 # description: Redis is a ...
- 解决dubbo-admin管控台不能显示服务的问题
1.首先在网上下载了dubbo-admin.war,解压后修改dubbo.properties文件 dubbo.registry.address=zookeeper://127.0.0.1:2181 ...
- python实现各种排序
1.冒泡排序: # -*- coding: utf-8 -*- def BubbleSort(a): n=len(a) for i in range(0,n-1): swapped=False for ...
- Spring Cloud程序报错总结
1.com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: 原因如下: 在默认设置下,Eureka服务 ...