[BZOJ 1146] [CTSC2008]网络管理Network(树状数组+主席树)
题目描述
M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门。为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络。该网络的结构由N个路由器和N-1条高速光缆组成。每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部门进行通信联络。该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信。 高速光缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略。但是由于路由器老化,在这些路由器上进行数据交换会带来很大的延迟。而两个路由器之间的通信延迟时间则与这两个路由器通信路径上所有路由器中最大的交换延迟时间有关。作为M公司网络部门的一名实习员工,现在要求你编写一个简单的程序来监视公司的网络状况。该程序能够随时更新网络状况的变化信息(路由器数据交换延迟时间的变化),并且根据询问给出两个路由器通信路径上延迟第k大的路由器的延迟时间。
【任务】 你的程序从输入文件中读入N个路由器和N-1条光缆的连接信息,每个路由器初始的数据交换延迟时间Ti,以及Q条询问(或状态改变)的信息。并依次处理这Q条询问信息,它们可能是:
由于更新了设备,或者设备出现新的故障,使得某个路由器的数据交换延迟时间发生了变化。
查询某两个路由器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!”(全部小写不包含引号,两个单词之间有一个空格)。
输入输出样例
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
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(树状数组+主席树)的更多相关文章
- BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 3522 Solved: 1041[Submi ...
- 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- zoj2112 树状数组+主席树 区间动第k大
Dynamic Rankings Time Limit: 10000MS Memory Limit: 32768KB 64bit IO Format: %lld & %llu Subm ...
- BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树
BZOJ_1901_Zju2112 Dynamic Rankings_树状数组+主席树 题意: 给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i, ...
- 【bzoj3744】Gty的妹子序列 分块+树状数组+主席树
题目描述 我早已习惯你不在身边, 人间四月天 寂寞断了弦. 回望身后蓝天, 跟再见说再见…… 某天,蒟蒻Autumn发现了从 Gty的妹子树(bzoj3720) 上掉落下来了许多妹子,他发现 她们排成 ...
- BZOJ_2120_数颜色_Set+树状数组+主席树
BZOJ_2120_数颜色_Set+树状数组+主席树 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L ...
- P1972 [SDOI2009]HH的项链[离线+树状数组/主席树/分块/模拟]
题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链 ...
- BZOJ 1146: [CTSC2008]网络管理Network( 树链剖分 + 树状数组套主席树 )
树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...
- BZOJ 1146: [CTSC2008]网络管理Network 树链剖分+线段树+平衡树
1146: [CTSC2008]网络管理Network Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 870 Solved: 299[Submit] ...
- 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...
随机推荐
- XKC's basketball team【线段树查询】
XKC , the captain of the basketball team , is directing a train of nn team members. He makes all mem ...
- hdoj4276(树形dp+分组背包)
题目链接:https://vjudge.net/problem/HDU-4276 题意:给出一棵树,起点为1,时间为V,终点为n,每个点有一个价值a[u],每条边有一个时间花费w,求在时间V内到达终点 ...
- Linux Crontab格式说明
Crontab基本格式: * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 第4 ...
- 【LOJ】#3097. 「SNOI2019」通信
LOJ#3097. 「SNOI2019」通信 费用流,有点玄妙 显然按照最小路径覆盖那题的建图思路,把一个点拆成两种点,一种是从这个点出去,标成\(x_{i}\),一种是输入到这个点,使得两条路径合成 ...
- 创建安全的 Netty 程序
1.使用 SSL/TLS 创建安全的 Netty 程序 SSL 和 TLS 是众所周知的标准和分层的协议,它们可以确保数据时私有的 Netty提供了SSLHandler对网络数据进行加密 使用Http ...
- (十三)springMvc 处理 Json
目录 文章目录 为什么用 Json 处理 json 的流程 环境准备 配置 json 转换器 后记 更新 为什么用 Json Json 格式简单,语法简单,解析简单 : 处理 json 的流程 判断客 ...
- cdoj 574 High-level ancients dfs序+线段树 每个点所加权值不同
High-level ancients Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/s ...
- LeetCode. 矩阵中的最长递增路径
题目要求: 给定一个整数矩阵,找出最长递增路径的长度. 对于每个单元格,你可以往上,下,左,右四个方向移动. 你不能在对角线方向上移动或移动到边界外(即不允许环绕). 示例: 输入: nums = [ ...
- python 基础(十五)--time和datatime模块
time模块 time.time():返回当前时间,时间戳 time.clock():返回cpu时间(?),当有time.sleep()时,time.clock()不计时 time.localtime ...
- S02_CH03_EMIO实验Enter a post title
S02_CH03_EMIO实验 3.1 EMIO 和MIO的对比介绍 上次讲到MIO的使用,初步熟悉了EDK的使用,这次就来说说EMIO的使用.如你所见zynq的GPIO,分为两种,MIO(multi ...