BZOJ 1146 网络管理Network(树链剖分+BST)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1146
题意:给出一棵树,每个节点有一个权值。两种操作:(1) 修改某个节点的权值;(2)询问a到b路径上第K大的权值。
思路:首先,DFS两次得到树链(重新标号,一个树链上的节点的标号连续)。建立线段树,再为线段树每个节点建立一棵BST。(1)修改时,在线段树上依次向下修改,并且到达每个节点时要修改相应的BST,即删掉原来的权值,插入新的权值,复杂度(logn)^2;(2)查询:转化成区间第K小的。计算出(a,b)的最近公共祖先lca。二分答案x,在路径(a,lca)和(b,lca)上分别计算小于等于x的节点个数。比如计算(a,lca),就是顺着a所在树链依次向上,最多有logn个树链,然后在每个树链上查找,其实就是在线段树上查找,整个复杂度是(logn)^3。
vector<int> g[N];
int leaf[N],f[N][20],size[N],a[N],id[N],wh[N];
int visit[N],dep[N],head[N];
int T;
void dfs(int u)
{
visit[u]=1; size[u]=1;
int i,v;
FOR0(i,SZ(g[u]))
{
v=g[u][i];
if(visit[v]) continue;
f[v][0]=u;
dep[v]=dep[u]+1;
dfs(v);
size[u]+=size[v];
}
if(size[u]==1) leaf[u]=1;
}
void DFS(int u,int top)
{
head[u]=top; id[++T]=u; wh[u]=T;
if(leaf[u]) return;
int maxSon,Max=-1;
int i,v;
FOR0(i,SZ(g[u]))
{
v=g[u][i];
if(v==f[u][0]) continue;
if(size[v]>Max) Max=size[v],maxSon=v;
}
DFS(maxSon,top);
FOR0(i,SZ(g[u]))
{
v=g[u][i];
if(v!=maxSon&&v!=f[u][0]) DFS(v,v);
}
}
int n,m;
void init()
{
RD(n,m);
int i,x,y;
FOR1(i,n) RD(a[i]);
FOR1(i,n-1)
{
RD(x,y);
g[x].pb(y);
g[y].pb(x);
}
dfs(1); DFS(1,1);
int j;
for(i=1;(1<<i)<=n;i++)
{
for(j=1;j<=n;j++) f[j][i]=f[f[j][i-1]][i-1];
}
}
int getLca(int x,int y)
{
if(x==y) return x;
if(dep[x]>dep[y]) swap(x,y);
int t=dep[y]-dep[x],i;
for(i=0;i<20;i++) if(t&(1<<i))
{
y=f[y][i];
}
if(x==y) return x;
for(i=19;i>=0;i--)
{
if(f[x][i]!=f[y][i]&&f[x][i]&&f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
struct node
{
int L,R,size,cnt,key;
};
struct Node
{
int L,R,root;
};
node tree[N<<5];
Node segTree[N<<2];
int e;
int newNode(int key)
{
e++;
tree[e].key=key;
tree[e].L=tree[e].R=0;
tree[e].cnt=1;
tree[e].size=1;
return e;
}
void insert(int x,int key)
{
int p=x;
while(1)
{
tree[p].size++;
if(tree[p].key==key)
{
tree[p].cnt++;
return;
}
if(tree[p].key<key)
{
if(tree[p].R==0)
{
tree[p].R=newNode(key);
return;
}
else p=tree[p].R;
}
else
{
if(tree[p].L==0)
{
tree[p].L=newNode(key);
return;
}
else p=tree[p].L;
}
}
}
void build(int t,int L,int R)
{
segTree[t].L=L;
segTree[t].R=R;
segTree[t].root=newNode(a[id[L]]);
if(L==R) return;
int mid=(L+R)>>1;
build(t*2,L,mid);
build(t*2+1,mid+1,R);
int i;
for(i=L+1;i<=R;i++) insert(segTree[t].root,a[id[i]]);
}
void del(int x,int key)
{
int p=x;
while(1)
{
tree[p].size--;
if(tree[p].key==key)
{
tree[p].cnt--;
return;
}
if(key<tree[p].key) p=tree[p].L;
else p=tree[p].R;
}
}
void modify(int t,int pos,int x,int y)
{
del(segTree[t].root,x);
insert(segTree[t].root,y);
if(segTree[t].L==segTree[t].R) return;
int mid=(segTree[t].L+segTree[t].R)>>1;
if(pos<=mid) modify(t*2,pos,x,y);
else modify(t*2+1,pos,x,y);
}
int cal(int x,int key)
{
int ans=0,p=x;
while(p)
{
if(key==tree[p].key)
{
ans+=tree[p].size-tree[tree[p].R].size;
return ans;
}
if(key<tree[p].key) p=tree[p].L;
else
{
ans+=tree[p].size-tree[tree[p].R].size;
p=tree[p].R;
}
}
return ans;
}
int query(int t,int L,int R,int key)
{
if(segTree[t].L==L&&segTree[t].R==R)
{
return cal(segTree[t].root,key);
}
int mid=(segTree[t].L+segTree[t].R)>>1;
if(R<=mid) return query(t*2,L,R,key);
if(L>mid) return query(t*2+1,L,R,key);
return query(t*2,L,mid,key)+query(t*2+1,mid+1,R,key);
}
int query(int L,int R,int key)
{
int ans=0;
while(head[L]!=head[R])
{
ans+=query(1,wh[head[L]],wh[L],key);
L=f[head[L]][0];
}
ans+=query(1,wh[R],wh[L],key);
return ans;
}
int calKth(int x,int y,int lca,int K)
{
int low=0,high=INF,mid,ans,cnt;
while(low<=high)
{
mid=(low+high)>>1;
cnt=query(x,lca,mid)+query(y,lca,mid);
if(a[lca]<=mid) cnt--;
if(cnt>=K) ans=mid,high=mid-1;
else low=mid+1;
}
return ans;
}
int main()
{
init(); build(1,1,n);
int op,x,y,lca,cnt;
while(m--)
{
RD(op); RD(x,y);
if(op==0) modify(1,wh[x],a[x],y),a[x]=y;
else
{
lca=getLca(x,y);
cnt=dep[x]+dep[y]-dep[lca]*2+1;
if(cnt<op) puts("invalid request!");
else PR(calKth(x,y,lca,cnt-op+1));
}
}
}
BZOJ 1146 网络管理Network(树链剖分+BST)相关推荐
- BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )
树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...
- BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组
欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...
- BZOJ 2243 染色(树链剖分好题)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 7971 Solved: 2990 [Submit][Stat ...
- BZOJ 4034 [HAOI2015]T2 树链剖分
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
- BZOJ 4034: [HAOI2015]T2 树链剖分
4034: [HAOI2015]T2 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操 ...
- bzoj 4127: Abs(树链剖分+线段树)
4127: Abs Time Limit: 40 Sec Memory Limit: 256 MB Submit: 667 Solved: 225 [Submit][Status][Discuss ...
- 【bzoj1146】 [CTSC2008]网络管理Network【树链剖分+树套树+二分 线段树套Treap】
1146: [CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公 ...
- BZOJ 2157 「国家集训队」旅游(树链剖分,线段树,边权转点权)【BZOJ计划】
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 题目链接 https://hydro.ac/d/bzoj/p/2157 是 hydro 的 BZOJ ...
- BZOJ 2402 陶陶的难题II (树链剖分、线段树、凸包、分数规划)
毒瘤,毒瘤,毒瘤-- \(30000\)这个数据范围,看上去就是要搞事的啊... 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2402 ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
最新文章
- 空间金字塔方法表示图像
- 【模板】最小割树(Gomory-Hu Tree)
- kill session-KILL_SESSION()
- Linux/Windows/MacOS各个操作系统下推荐应用集合
- Consecutive Sum LightOJ - 1269(区间异或和)
- 微软软件推送服务器,微软将通过系统更新功能向大部分用户推送新版Microsoft Edge浏览器-...
- 解决Jenkins上git出现的“ERROR: Error fetching remote repo ‘origin‘”问题
- 摩拜服务器维护,摩拜的后台是云服务器
- MPU6050 六轴传感器实验
- QT修改releas发布的exe图标
- 和计算机相关的祝福语,祝福语精选
- 数字人还能设计数字藏品?希加加xQee创作人间十二月
- vue element-ui 键盘输入enter键 触发事件
- python的round函数使用
- 交换机(三层)接入层、汇聚层和核心层交换机的特点
- 加班、加人、延期是糟糕的办法
- 手机微信中对方正在输入...,不显示有4种原因,还能永不显示
- SpringSecurity 安全框架
- 见微知著,从小需求里看产品的抉择和定位
- 安装测试包(.ipa)到iPhone手机
热门文章
- Atitit 遗留系统的改造 微创技术 attilax总结 目录 1. 微创是高科技带来的革命!	1 1.1. 早期微创	1 1.2. 微创五大优点	1 2. 常用辅助设备与模块	2 2.1. 清晰
- Atitit 让maven pom.xml不编译 1.build 2. defaultGoalinstall/defaultGoal 3. directory${bas
- paip.互联网产品要成功的要素
- AJAX在IE下的调试
- 从毫无交集到走向融合,AI+区块链才是改变世界的黑科技!
- 一个空格引发的Bug! ----CSV输出和CSV读入
- 【精品分享】Kolla 让 OpenStack 部署更贴心
- 英特尔王庆连续四年担任OpenStack基金会个人独立董事
- 计算机技巧网站,13个实用电脑技巧汇总
- 如何更新计算机的flash player,如何在win7电脑中Adobe Flash Player自动更新?