题目描述

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

【任务】 你的程序从输入文件中读入N个路由器和N-1条光缆的连接信息,每个路由器初始的数据交换延迟时间Ti,以及Q条询问(或状态改变)的信息。并依次处理这Q条询问信息,它们可能是:

  1. 由于更新了设备,或者设备出现新的故障,使得某个路由器的数据交换延迟时间发生了变化。

  2. 查询某两个路由器a和b之间的路径上延迟第k大的路由器的延迟时间。

输入输出格式

输入格式:

第一行为两个整数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大的路由器的延迟时间。注意a可以等于b,此时路径上只有一个路由器。

输出格式:

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

输入输出样例

输入样例#1: 复制

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
输出样例#1: 复制

3
2
2
invalid request!

说明

测试数据满足N,Q<=80000,任意一个路由器在任何时刻都满足延迟时间小于10^8。对于所有询问满足0<=K<=N 。

题解

  带修树链第k大

  据说能用树剖+线段树套平衡树4个log稳过?

  据说能用树剖+树状数组套主席树3个log?

  据说能把树剖去了两个log?

  据说还能一个log?

  蒟蒻表示很懵逼……只会用树状数组套主席树的……

  首先这是一棵树,要在树上跑主席树两种方法,一种是每一次在父亲的树的基础上加值,然而那样就不资瓷修改了(大概?蒟蒻也不是很清楚)

  或者用括号序列的思想,每一个点dfs进的时候存个点,出去的时候存个点,这样就可以用差分来跑主席树了(具体细节看代码)

  然后是修改……我就当你们都会待修改主席树了(不懂的可以去看看这道题->动态逆序对

  然后……大概就这样?

  时间复杂度应该是两个log吧(树剖用来求LCA的应该不算在里面)

  ps:调主席树update的时候写成$ch[x][0]$和$ch[x][1]$了……调了半天啥错都找不到orz

 //minamoto
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=;
struct node{
int op,x,y;
}Q[N];
int n,m,q,b[N<<],lim;
int rt[N<<],L[N<<],R[N<<],sz[N<<],cnt;
void update(int &p,int l,int r,int pos,int val){
if(!p) p=++cnt;sz[p]+=val;
if(l==r) return;
int mid=l+r>>;
if(pos<=mid) update(L[p],l,mid,pos,val);
else update(R[p],mid+,r,pos,val);
}
void update(int x,int val,int op){
for(;x<=m;x+=x&-x) update(rt[x],,lim,val,op);
}
int ver[N<<],Next[N<<],head[N],tot;
int fa[N],dep[N],top[N],size[N],son[N],ls[N],rs[N],sum[N],val[N],num;
inline void add(int u,int v){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot;
}
void dfs1(int u){
size[u]=,dep[u]=dep[fa[u]]+;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa[u]){
fa[v]=u,dfs1(v),size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
}
}
void dfs2(int u,int t){
top[u]=t,ls[u]=++num;
update(ls[u],val[u],);
if(son[u]){
dfs2(son[u],t);
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
}
rs[u]=++num;
update(rs[u]+,val[u],-);
}
int LCA(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
int sta[],stb[],cnta,cntb;
inline void get(int x,int op){
if(~op){
for(;x;x-=x&-x) sta[++cnta]=rt[x];
}
else{
for(;x;x-=x&-x) stb[++cntb]=rt[x];
}
}
int query(int l,int r,int k){
if(l==r) return b[l];
int mid=l+r>>,sum=;
for(int i=;i<=cnta;++i) sum+=sz[R[sta[i]]];
for(int i=;i<=cntb;++i) sum-=sz[R[stb[i]]];
if(sum>=k){
for(int i=;i<=cnta;++i) sta[i]=R[sta[i]];
for(int i=;i<=cntb;++i) stb[i]=R[stb[i]];
return query(mid+,r,k);
}
else{
for(int i=;i<=cnta;++i) sta[i]=L[sta[i]];
for(int i=;i<=cntb;++i) stb[i]=L[stb[i]];
return query(l,mid,k-sum);
}
}
inline void getans(int u,int v,int k){
int lca=LCA(u,v);
if(k>dep[u]+dep[v]-(dep[lca]<<)+) return (void)(puts("invalid request!"));
cnta=cntb=;
get(ls[u],),get(ls[lca],-);
get(ls[v],),get(ls[fa[lca]],-);
printf("%d\n",query(,lim,k));
}
inline void change(int pos,int v){
update(ls[pos],val[pos],-),update(rs[pos]+,val[pos],),val[pos]=v;
update(ls[pos],v,),update(rs[pos]+,v,-);
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),q=read(),m=n<<;
for(int i=;i<=n;++i) b[++lim]=val[i]=read();
for(int i=;i<n;++i){
int u=read(),v=read();add(u,v);
}
for(int i=;i<=q;++i){
int op=read(),x=read(),y=read();
Q[i]=(node){op,x,y};
if(!op) b[++lim]=y;
}
sort(b+,b++lim),lim=unique(b+,b++lim)-b-;
for(int i=;i<=n;++i) val[i]=lower_bound(b+,b++lim,val[i])-b;
dfs1(),dfs2(,);
for(int i=;i<=q;++i){
int op=Q[i].op,x=Q[i].x,y=Q[i].y;
if(op) getans(x,y,op);
else y=lower_bound(b+,b++lim,y)-b,change(x,y);
}
return ;
}

[BZOJ 1146] [CTSC2008]网络管理Network(树状数组+主席树)的更多相关文章

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

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

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

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

  3. zoj2112 树状数组+主席树 区间动第k大

    Dynamic Rankings Time Limit: 10000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu Subm ...

  4. BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树

    BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...

  5. 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树

    题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...

  6. BZOJ_2120_数颜色_Set+树状数组+主席树

    BZOJ_2120_数颜色_Set+树状数组+主席树 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L ...

  7. P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]

    题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...

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

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

  9. BZOJ 1146: [CTSC2008]网络管理Network 树链剖分+线段树+平衡树

    1146: [CTSC2008]网络管理Network Time Limit: 50 Sec  Memory Limit: 162 MBSubmit: 870  Solved: 299[Submit] ...

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

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

随机推荐

  1. ubuntu配置vnc服务

    今晚比较闲,就用ubuntu系统搭了vnc系统,真的好用(比centos简单多了). 简单介绍下,VNC(Virtual Network Computing)服务是一款优秀的屏幕分享及远程连接服务,基 ...

  2. 2019icpc南昌网络赛

    B. Fire-Fighting Hero (dijstra优先队列+bfs) 题意:刚开始看错题了,以为是k次dijkstra,但是wa了,后来队友指正后发现挺水的.求S到其它点的最短路的最大值an ...

  3. kafka2.10集群搭建(一)

    一.kafka集群搭建 1.上传解压 2.配置文件的配置 1.修改 server.properties文件 broker.id=11 #192.168.199.11 #21 一般使用ip后三位 lis ...

  4. 【AtCoder】AGC001

    AGC001 A - BBQ Easy 从第\(2n - 1\)个隔一个加一下加到1即可 #include <bits/stdc++.h> #define fi first #define ...

  5. Kubernetes---Pod笔记

    ⒈pod的理解     将多个容器镜像融合在一起,共享网络命名空间及容器卷 ⒉pod的分类 自助式podv          不是被控制器管理的pod,它一旦死亡不会被人给拉起来. 控制器管理的pod ...

  6. 20190716-Python网络数据采集/第 2 章 复杂HTML解析

    # P29/9# 解析,要考虑到可持续性问题,对方反爬修改后,仍继续有效,方为优秀代码# 解析一个目标网页前,需要做到以下几点:(1)明确目标内容:(2)寻找“打印此页”的链接,或查看网站有无HTML ...

  7. vue开发环境配置跨域,一步到位

    本文要实现的是:使用vue-cli搭建的项目在开发时配置跨域,上线后不做任何任何修改,接口也可以访问,前端跨域解决方案 production:产品 生产环境 development:开发 开发环境 1 ...

  8. Codeforces 1097E. Egor and an RPG game

    传送门 首先考虑怎么算 $f(n)$ (就是题目里面那个 $f(n)$) 发现可以构造一组序列大概长这样: ${1,3,2,6,5,4,10,9,8,7,15,14,13,12,11,...,n(n+ ...

  9. c#学习笔记-string stringBuilder

    string aTest = "abc";//分配固定的内存大小 aTest += "ddd"; //销毁原先的数据再来分配,消耗大 StringBuilder ...

  10. 用于Linq的去重 Distinct

            /// <summary>         /// 用于Linq的去重,扩展方法需要放到静态类中         /// </summary>          ...