【BZOJ1146】[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个,则输出信息“invalid request!”(全部小写不包含引号,两个单词之间有一个空格)。

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!

题解:用树状数组+主席树维护DFS序即可。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=80010;
int n,m,N,nm,cnt,tot,l1,l2,l3,l4;
int p[maxn],q[maxn],s1[maxn],s2[maxn],s3[maxn],s4[maxn],v[maxn],pa[maxn],pb[maxn],pc[maxn];
int to[maxn<<1],next[maxn<<1],head[maxn],fa[18][maxn],dep[maxn],rt[maxn],ref[maxn<<1];
struct number
{
int val,org;
}num[maxn<<1];
struct node
{
int siz,ls,rs;
}s[maxn*160];
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
bool cmp(number a,number b)
{
return a.val<b.val;
}
void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
void dfs(int x)
{
p[x]=++q[0];
for(int i=head[x];i!=-1;i=next[i])
{
if(to[i]==fa[0][x]) continue;
fa[0][to[i]]=x,dep[to[i]]=dep[x]+1,dfs(to[i]);
}
q[x]=q[0];
}
void insert(int &x,int l,int r,int pos,int v)
{
if(!x) x=++tot;
s[x].siz+=v;
if(l==r) return ;
int mid=l+r>>1;
if(pos<=mid) insert(s[x].ls,l,mid,pos,v);
else insert(s[x].rs,mid+1,r,pos,v);
}
void updata(int x,int y,int v)
{
for(int i=x;i<=n;i+=i&-i) insert(rt[i],1,N,y,v);
}
int query(int l,int r,int pos)
{
if(!pos) printf("fuck\n");
if(l==r) return ref[l];
int sr=0,mid=l+r>>1,i;
for(i=1;i<=l1;i++) sr+=s[s[s1[i]].rs].siz;
for(i=1;i<=l2;i++) sr+=s[s[s2[i]].rs].siz;
for(i=1;i<=l3;i++) sr-=s[s[s3[i]].rs].siz;
for(i=1;i<=l4;i++) sr-=s[s[s4[i]].rs].siz;
if(pos<=sr)
{
for(i=1;i<=l1;i++) s1[i]=s[s1[i]].rs;
for(i=1;i<=l2;i++) s2[i]=s[s2[i]].rs;
for(i=1;i<=l3;i++) s3[i]=s[s3[i]].rs;
for(i=1;i<=l4;i++) s4[i]=s[s4[i]].rs;
return query(mid+1,r,pos);
}
else
{
for(i=1;i<=l1;i++) s1[i]=s[s1[i]].ls;
for(i=1;i<=l2;i++) s2[i]=s[s2[i]].ls;
for(i=1;i<=l3;i++) s3[i]=s[s3[i]].ls;
for(i=1;i<=l4;i++) s4[i]=s[s4[i]].ls;
return query(l,mid,pos-sr);
}
}
int lca(int a,int b)
{
if(dep[a]<dep[b]) swap(a,b);
int i;
for(i=17;~i;i--) if(dep[fa[i][a]]>=dep[b]) a=fa[i][a];
if(a==b) return a;
for(i=17;~i;i--) if(fa[i][a]!=fa[i][b]) a=fa[i][a],b=fa[i][b];
return fa[0][a];
}
int main()
{
n=rd(),m=rd();
int i,j,a,b,c,d,e;
memset(head,-1,sizeof(head));
for(i=1;i<=n;i++) num[++nm].val=rd(),num[nm].org=i;
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
dep[1]=1,dfs(1);
for(j=1;(1<<j)<=n;j++) for(i=1;i<=n;i++) fa[j][i]=fa[j-1][fa[j-1][i]];
for(i=1;i<=m;i++)
{
pc[i]=rd(),pa[i]=rd(),pb[i]=rd();
if(!pc[i]) num[++nm].val=pb[i],num[nm].org=n+i;
}
sort(num+1,num+nm+1,cmp);
for(i=1;i<=nm;i++)
{
if(num[i].val>ref[N]) ref[++N]=num[i].val;
if(num[i].org<=n) v[num[i].org]=N;
else pb[num[i].org-n]=N;
}
for(i=1;i<=n;i++) updata(p[i],v[i],1),updata(q[i]+1,v[i],-1);
for(i=1;i<=m;i++)
{
c=pc[i],a=pa[i],b=pb[i];
if(!c)
{
updata(p[a],v[a],-1),updata(q[a]+1,v[a],1),v[a]=b,updata(p[a],b,1),updata(q[a]+1,b,-1);
}
else
{
d=lca(a,b),e=fa[0][d],l1=l2=l3=l4=0;
if(dep[a]+dep[b]-dep[d]-dep[e]<c)
{
printf("invalid request!\n");
continue;
}
for(j=p[a];j;j-=j&-j) s1[++l1]=rt[j];
for(j=p[b];j;j-=j&-j) s2[++l2]=rt[j];
for(j=p[d];j;j-=j&-j) s3[++l3]=rt[j];
for(j=p[e];j;j-=j&-j) s4[++l4]=rt[j];
printf("%d\n",query(1,N,c));
}
}
return 0;
}//5 5 5 1 2 3 4 3 1 2 1 4 3 5 3 1 1 1 1 1 5 2 1 5 3 1 5 2 1 2

【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树的更多相关文章

  1. 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序

    [题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...

  2. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  3. 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序

    3881: [Coci2015]Divljak Time Limit: 20 Sec  Memory Limit: 768 MBSubmit: 508  Solved: 158[Submit][Sta ...

  4. 【BZOJ-1103】大都市meg 树状数组 + DFS序

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2009  Solved: 1056[Submit][Sta ...

  5. POJ 3321 Apple Tree (树状数组+dfs序)

    题目链接:http://poj.org/problem?id=3321 给你n个点,n-1条边,1为根节点.给你m条操作,C操作是将x点变反(1变0,0变1),Q操作是询问x节点以及它子树的值之和.初 ...

  6. BZOJ 1103 [POI2007]大都市meg(树状数组+dfs序)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1103 [题目大意] 给出一棵树,每条边的经过代价为1,现在告诉你有些路不需要代价了, ...

  7. [luogu P3787][新创无际夏日公开赛] 冰精冻西瓜 [树状数组][dfs序]

    题目背景 盛夏,冰之妖精琪露诺发现了一大片西瓜地,终于可以吃到美味的冻西瓜啦. 题目描述 琪露诺是拥有操纵冷气程度的能力的妖精,一天她发现了一片西瓜地.这里有n个西瓜,由n-1条西瓜蔓连接,形成一个有 ...

  8. HDU5293(SummerTrainingDay13-B Tree DP + 树状数组 + dfs序)

    Tree chain problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  9. BZOJ.2434.[NOI2011]阿狸的打字机(AC自动机 树状数组 DFS序)

    题目链接 首先不需要存储每个字符串,可以将所有输入的字符依次存进Trie树,对于每个'P',记录该串结束的位置在哪,以及当前节点对应的是第几个串(当前串即根节点到当前节点):对于'B',只需向上跳一个 ...

随机推荐

  1. LeetCode OJ-- Maximum Subarray @

    https://oj.leetcode.com/problems/maximum-subarray/ 给了一个数组一列数,求其中的连续子数组的最大和. O(n)复杂度 class Solution { ...

  2. Codeforces Round #450 (Div. 2) B. Position in Fraction【数论/循环节/给定分子m 分母n和一个数c,找出c在m/n的循环节第几个位置出现,没出现过输出-1】

    B. Position in Fraction time limit per test 1 second memory limit per test 256 megabytes input stand ...

  3. FZU 2125 简单的等式 【数学/枚举解方程式】

    现在有一个等式如下:x^2+s(x,m)x-n=0.其中s(x,m)表示把x写成m进制时,每个位数相加的和.现在,在给定n,m的情况下,求出满足等式的最小的正整数x.如果不存在,请输出-1. Inpu ...

  4. BZOJ 3881 COCI 2015 Divljak

    题面 Description Tom有n个字符串S1,S2...Sn,Jerry有一个字符串集合T,一开始集合是空的. 接下来会发生q个操作,操作有两种形式: "1 P",Jerr ...

  5. MySQL开发36条军规

    转载地址:http://blog.itpub.net/22664653/viewspace-723506/ 写在前面的话: 总是在灾难发生后,才想起容灾的重要性: 总是在吃过亏后,才记得曾经有人提醒过 ...

  6. 2017.2.12 开涛shiro教程-第七章-与Web集成

    2017.2.9 开涛shiro教程-第七章-与Web集成(一) 原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. ...

  7. CocoaAsyncSocket使用笔记

    先去github的站点下载最新的包,然后先看看介绍. 写的比較具体了 https://github.com/robbiehanson/CocoaAsyncSocket/wiki/Intro_GCDAs ...

  8. Github css加载失败,样式混乱解决办法

    github被墙的解决办法 Github css加载失败,样式混乱解决办法   打开cmd,输入  nslookup github.com 8.8.8.8  ,下面就会显示出github的服务器地址列 ...

  9. JavaScript replace 回调函数用法

    params.query = params.query.replace(/[\+\-\&\|\!\(\)\{\}\[\]\^\"\~\*\?\:\\]/g,function(a){ ...

  10. vue key 的另外一个用法 过度

    key也可以用于强制替换元素/组件而不是重复使用它.当你遇到如下场景时它可能会很有用: 完整地触发组件的生命周期钩子 触发过渡 例如: <transition> <span :key ...