题目描述

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. POJ2195 Going Home【KM最小匹配】

    题目链接:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  2. (模板)求逆矩阵luoguP4783

    题目链接:https://www.luogu.org/problem/P4783 题意:求矩阵的逆. 思路:高斯消元法求矩阵的逆,n为400,卡常,我是开了O2优化才AC的.. AC代码: #incl ...

  3. HttpServletResponse对象(转)

    Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和response对象即然代表请求和响应,那我们要 ...

  4. NOIP 2018 提高组初赛试题 题目+答案+简要解析

    一.单项选择题(共 10  题,每题 2  分,共计 20  分: 每题有且仅有一个正确选项)       1. 下列四个不同进制的数中,与其它三项数值上不相等的是( ). A. (269) 16 B ...

  5. Laravel入门

    一.下载Laravel ①github上下载 ②通过composer下载,推荐 第一步,选择你要在哪个目录下载Laravel,打开cmd 第二步,打开https://docs.golaravel.co ...

  6. python-----模块【第一部分】-----

    一.hashlib(md5) import hashlib obj = hashlib.md5('dsfd'.encode('utf-8')) obj.update('123'.encode('utf ...

  7. 20190806-Python基础 第二章 列表和元组(3)元组&章小结

    元组,不可修改的序列(与列表的唯一差别) 1. 元组用圆括号括起,用逗号分隔 2. 如果只有一个值,也必须在后面加上逗号 print((42)) print((42,)) 结果: 42 (42,) p ...

  8. Timezone offset does not match system offset: 0 != -32400. Please, check your config files

    apscheduler使用uWSGI的mule模块部署的时候报错, 因为系统时区和代码运行时区不一样导致. 解决办法:在初始化的时候指定上海的时区 scheduler = BlockingSchedu ...

  9. bzoj 2734 集合悬殊 (状压dp)

    大意: 给定$n$, 求集合{1,2,...n}的子集数, 满足若$x$在子集内, 则$2x,3x$不在子集内. 记$f(x)$为$x$除去所有因子2,3后的数, 那么对于所有$f$值相同的数可以划分 ...

  10. GAN——ModeCollapse

    GAN——ModeCollapse 2017年05月21日 13:54:31 LiuSpark 阅读数 6821更多 分类专栏: 机器学习   版权声明:本文为博主原创文章,遵循CC 4.0 BY-S ...