BZOJ_1146_[CTSC2008]网络管理Network_主席树

Description

  M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门。为了让分布在世界各地的N个
部门之间协同工作,公司搭建了一个连接整个公司的通信网络。该网络的结构由N个路由器和N-1条高速光缆组成。
每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部
门进行通信联络。该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信。 高速光
缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略。但是由于路由器老化,在这些路由器上进行
数据交换会带来很大的延迟。而两个路由器之间的通信延迟时间则与这两个路由器通信路径上所有路由器中最大的
交换延迟时间有关。作为M公司网络部门的一名实习员工,现在要求你编写一个简单的程序来监视公司的网络状况
。该程序能够随时更新网络状况的变化信息(路由器数据交换延迟时间的变化),并且根据询问给出两个路由器通
信路径上延迟第k大的路由器的延迟时间。【任务】 你的程序从输入文件中读入N个路由器和N-1条光缆的连接信息
,每个路由器初始的数据交换延迟时间Ti,以及Q条询问(或状态改变)的信息。并依次处理这Q条询问信息,它们
可能是: 1. 由于更新了设备,或者设备出现新的故障,使得某个路由器的数据交换延迟时间发生了变化。 2. 查
询某两个路由器a和b之间的路径上延迟第k大的路由器的延迟时间。

Input

第一行为两个整数N和Q,分别表示路由器总数和询问的总数。
第二行有N个整数,第i个数表示编号为i的路由器初始的数据延迟时间Ti。
紧接着N-1行,每行包含两个整数x和y。表示有一条光缆连接路由器x和路由器y。
紧接着是Q行,每行三个整数k、a、b。
如果k=0,则表示路由器a的状态发生了变化,它的数据交换延迟时间由Ta变为b
如果k>0,则表示询问a到b的路径上所经过的所有路由器(包括a和b)中延迟
第k大的路由器的延迟时间。
注意N,Q<=80000,任意一个路由器在任何时刻都满足延迟时间小于10^8。
对于所有询问满足0<=K<=N

Output

对于每一个第二种询问(k>0),输出一行。包含一个整数为相应的延迟时间。
如果路径上的路由器不足k个,则输出信息“invalidrequest!”
(全部小写不包含引号,两个单词之间有一个空格)。

Sample Input

5 5
5 1 2 3 4
3 1
2 1
4 3
5 3
2 4 5
0 1 2
2 2 3
2 1 4
3 3 5

Sample Output

3
2
2
invalid request!

 一般来说主席树维护树上信息的时候都是每个点维护点到根路径上的信息。
但这样还是在树上,修改不是很方便,于是把它放到序列上。
建立出栈入栈序,每个点在入栈的地方+1,出栈的位置-1。
前缀和就是这个点到根路径上的信息,转化成了序列问题。
然后这些操作都用树状数组做一下即可。
我这里写的有隐患,不能认为子树中最后出现的结点+1就是出栈的位置。
因为如果维护一些别的信息时,需要修改那个结点的信息,这样前一个点的出栈位置维护的信息就会也被修改。
并且空间也要开两倍。
 
(第k大)
 
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 80050
#define maxn 100000000
int n,m,head[N],to[N<<1],nxt[N<<1],val[N],dfn[N],cnt,out[N];
int fa[N],top[N],son[N],size[N],dep[N],tot,A[N],B[N],C[N],D[N];
int siz[N*250],ls[N*250],rs[N*250],root[N];
inline void add(int u,int v) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void insert(int &y,int l,int r,int v,int c) {
if(!y) y=++tot; siz[y]+=c;
if(l==r) return ;
int mid=(l+r)>>1;
if(v<=mid) insert(ls[y],l,mid,v,c);
else insert(rs[y],mid+1,r,v,c);
}
void dfs1(int x,int y) {
int i; dep[x]=dep[y]+1; fa[x]=y; size[x]=1; dfn[x]=++dfn[0];
for(i=dfn[x];i<=n;i+=i&(-i)) insert(root[i],0,maxn,val[x],1);
for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
dfs1(to[i],x); size[x]+=size[to[i]]; if(size[to[i]]>size[son[x]]) son[x]=to[i];
}
for(i=dfn[0]+1;i<=n;i+=i&(-i)) insert(root[i],0,maxn,val[x],-1);
out[x]=dfn[0]+1;
}
void dfs2(int x,int t) {
top[x]=t; if(son[x]) dfs2(son[x],t); int i;
for(i=head[x];i;i=nxt[i]) if(to[i]!=fa[x]&&to[i]!=son[x]) dfs2(to[i],to[i]);
}
int lca(int x,int y) {
while(top[x]!=top[y]) {
if(dep[top[x]]>dep[top[y]]) swap(x,y);
y=fa[top[y]];
}
return dep[x]<dep[y]?x:y;
}
int query(int l,int r,int k) {
if(l==r) return l;
int mid=(l+r)>>1,i,sizls=0;
for(i=1;i<=A[0];i++) sizls+=siz[ls[A[i]]];
for(i=1;i<=B[0];i++) sizls+=siz[ls[B[i]]];
for(i=1;i<=C[0];i++) sizls-=siz[ls[C[i]]];
for(i=1;i<=D[0];i++) sizls-=siz[ls[D[i]]];
if(k<=sizls) {
for(i=1;i<=A[0];i++) A[i]=ls[A[i]];
for(i=1;i<=B[0];i++) B[i]=ls[B[i]];
for(i=1;i<=C[0];i++) C[i]=ls[C[i]];
for(i=1;i<=D[0];i++) D[i]=ls[D[i]];
return query(l,mid,k);
}else {
for(i=1;i<=A[0];i++) A[i]=rs[A[i]];
for(i=1;i<=B[0];i++) B[i]=rs[B[i]];
for(i=1;i<=C[0];i++) C[i]=rs[C[i]];
for(i=1;i<=D[0];i++) D[i]=rs[D[i]];
return query(mid+1,r,k-sizls);
}
}
int main() {
scanf("%d%d",&n,&m);
int i,x,y,k;
for(i=1;i<=n;i++) scanf("%d",&val[i]);
for(i=1;i<n;i++) {
scanf("%d%d",&x,&y); add(x,y); add(y,x);
}
dfs1(1,0); dfs2(1,1);
while(m--) {
scanf("%d%d%d",&k,&x,&y);
if(!k) {
for(i=dfn[x];i<=n;i+=i&(-i)) insert(root[i],0,maxn,val[x],-1);
for(i=out[x];i<=n;i+=i&(-i)) insert(root[i],0,maxn,val[x],1);
val[x]=y;
for(i=dfn[x];i<=n;i+=i&(-i)) insert(root[i],0,maxn,val[x],1);
for(i=out[x];i<=n;i+=i&(-i)) insert(root[i],0,maxn,val[x],-1);
}else {
A[0]=B[0]=C[0]=D[0]=0;
int l=lca(x,y),len=dep[x]+dep[y]-dep[l]-dep[fa[l]];
if(len<k) puts("invalid request!");
else {
k=len-k+1;
for(i=dfn[x];i;i-=i&(-i)) A[++A[0]]=root[i];
for(i=dfn[y];i;i-=i&(-i)) B[++B[0]]=root[i];
for(i=dfn[l];i;i-=i&(-i)) C[++C[0]]=root[i];
if(fa[l]) for(i=dfn[fa[l]];i;i-=i&(-i)) D[++D[0]]=root[i];
printf("%d\n",query(0,maxn,k));
}
}
}
}
/*
5 5
5 1 2 3 4
3 1
2 1
4 3
5 3
2 4 5
0 1 2
2 2 3
2 1 4
3 3 5
*/

BZOJ_1146_[CTSC2008]网络管理Network_主席树+树状数组的更多相关文章

  1. [CTSC2008]网络管理(整体二分+树剖+树状数组)

    一道经典的带修改树链第 \(k\) 大的问题. 我只想出三个 \(\log\) 的解法... 整体二分+树剖+树状数组. 那不是暴力随便踩的吗??? 不过跑得挺快的. \(Code\ Below:\) ...

  2. CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)

    The best programmers of Embezzland compete to develop a part of the project called "e-Governmen ...

  3. 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树

    [BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...

  4. BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )

    树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...

  5. 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...

  6. BZOJ1146[CTSC2008]网络管理——出栈入栈序+树状数组套主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个 部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条 ...

  7. 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

  8. [BZOJ 1146] [CTSC2008]网络管理Network(树状数组+主席树)

    题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...

  9. BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]

    1146: [CTSC2008]网络管理Network Time Limit: 50 Sec  Memory Limit: 162 MBSubmit: 3522  Solved: 1041[Submi ...

随机推荐

  1. List内存分配

    当采用默认构造函数List<int> value = new List<int>();实例化一个List<T>对象时,.Net Framework只是在内存中申请了 ...

  2. 玩转Git入门篇

    最近项目使用到Git管理项目,所以就学习了一番,随然网上关于 Git的文章铺天盖地,我还是整理下总结下自己学习Git相关笔记,希望也能帮助到需要他的小伙伴们,O(∩_∩)O~ 简介 Git 是分布式版 ...

  3. Java编程语言下Selenium 对于下拉框,单选,多选等选择器的操作

    WebElement selector = driver.findElement(By.id("Selector")); Select select = new Select(se ...

  4. "Uncaught object angular.js:36"诡异错误

    这个错误的调用顶级是jQuery.ready()函数,这个错误的原因是如果你在html元素里面定义ng-app,则在JavaScript里面必须初始化这个ngapp,初始化语句是: var AppNa ...

  5. (linux虚拟机)克隆得到的虚拟机修改网卡信息和IP地址,以及DNS

    克隆得到的虚拟机,与原先的系统是一模一样的包括MAC地址和IP地址.需要修改成信息. 克隆完事之后,首先在 点击生成一个新的MAC地址.然后启动,登陆. vim /etc/udev/rules.d/7 ...

  6. SOFA 源码分析 — 负载均衡和一致性 Hash

    前言 SOFA 内置负载均衡,支持 5 种负载均衡算法,随机(默认算法),本地优先,轮询算法,一致性 hash,按权重负载轮询(不推荐,已被标注废弃). 一起看看他们的实现(重点还是一致性 hash) ...

  7. Install and Configure Apache Kafka on Ubuntu 16.04

    https://devops.profitbricks.com/tutorials/install-and-configure-apache-kafka-on-ubuntu-1604-1/ by hi ...

  8. 【转】简单了介绍js中的一些概念(词法结构) 和 数据类型(部分)。

    1 , javascript字符集: javascript采用的是Unicode字符集编码. 为什么要采用这个编码呢? 原因很简单,16位的Unicode编码可以表示地球人的任何书面语言.这是语言 国 ...

  9. Vimium快捷键记录

    作为一个Geek必备的技能 从今天起在这里仅记录下使用过的快捷键和心得(翻译自 ?) version: 1.59 版本不同,快捷键有所不同 1. 下载安装地址(自备梯子) Chrome商店:https ...

  10. Oracle12c中分区(Partition)新特性之TRUNCATEPARTITION和EXCHANGE PARTITION级联功能

    TRUNCATE [SUB]PARTITION和EXCHANGE [SUB]PARTITION命令如今可以包括CASCADE子句,从而允许参照分区表向下级联这些操作.为确保该选项正常,相关外键也必须包 ...