[HNOI2016] 网络

来源:互联网 发布:sopcast网络电视如何用 编辑:程序博客网 时间:2024/05/21 16:58
P4054[Hnoi2016 day1]网络时间限制 : - MS   空间限制 : 165536 KB 评测说明 : 2s
问题描述

一个简单的网络系统可以被描述成一棵无根树。每个节点为一个服务器。连接服务器与服务器的数据线则看做
一条树边。两个服务器进行数据的交互时,数据会经过连接这两个服务器的路径上的所有服务器(包括这两个服务
器自身)。由于这条路径是唯一的,当路径上的某个服务器出现故障,无法正常运行时,数据便无法交互。此外,
每个数据交互请求都有一个重要度,越重要的请求显然需要得到越高的优先处理权。现在,你作为一个网络系统的
管理员,要监控整个系统的运行状态。系统的运行也是很简单的,在每一个时刻,只有可能出现下列三种事件中的
一种:1.  在某两个服务器之间出现一条新的数据交互请求;2.  某个数据交互结束请求;3.  某个服务器出现故
障。系统会在任何故障发生后立即修复。也就是在出现故障的时刻之后,这个服务器依然是正常的。但在服务器产
生故障时依然会对需要经过该服务器的数据交互请求造成影响。你的任务是在每次出现故障时,维护未被影响的请
求中重要度的最大值。注意,如果一个数据交互请求已经结束,则不将其纳入未被影响的请求范围。

输入格式

第一行两个正整数n,m,分别描述服务器和事件个数。服务器编号是从1开始的,因此n个服务器的编号依次是1
,2,3,…,n。接下来n-1行,每行两个正整数u,v,描述一条树边。u和v是服务器的编号。接下来m行,按发生时刻依
次描述每一个事件;即第i行(i=1,2,3,…,m)描述时刻i发生的事件。每行的第一个数type描述事件类型,共3种
类型:(1)若type=0,之后有三个正整数a,b,v,表示服务器a,b之间出现一条重要度为v的数据交互请求;(2)
若type=1,之后有一个正整数t,表示时刻t(也就是第t个发生的事件)出现的数据交互请求结束;(3)若type=2
,之后有一个正整数x,表示服务器x在这一时刻出现了故障。对于每个type为2的事件,就是一次询问,即询问“
当服务器x发生故障时,未被影响的请求中重要度的最大值是多少?”注意可能有某个服务器自身与自身进行数据
交互的情况。2 ≤ n ≤ 10^5, 1 ≤ m ≤ 2×10^5,其他的所有输入值不超过 10^9

输出格式

对于每个type=2的事件,即服务器出现故障的事件,输出一行一个整数,描述未被影响的请求中重要度的最大
值。如果此时没有任何请求,或者所有请求均被影响,则输出-1。

样例输入

13 23 
1 2 
1 3 
2 4 
2 5 
3 6 
3 7 
4 8 
4 9 
6 10 
6 11 
7 12 
7 13 
2 1 
0 8 13 3 
0 9 12 5 
2 9 
2 8 
2 2 
0 10 12 1 
2 2 
1 3 
2 7 
2 1 
0 9 5 6 
2 4 
2 5 
1 7 
0 9 12 4 
0 10 5 7 
2 1 
2 4 
2 12 
1 2 
2 5 
2 3 































样例输出

-1 


-1 

-1 







提示

分析:

      直接树链爆分+线段树(其实感觉并不算线段树,跟子节点都没什么关系)

      问题转化一下:求当前不经过这个点的路径的重要度 的最大值,动动脚趾就能发现,新增一条路径我们更新非此路径上的点即可

      线段树,每个节点两个大根堆,一个是新增的值,一个是删除的值,两堆堆顶元素相等就弹掉,询问,logn问下去,每个包含此位置的节点取堆顶,再取最大

#include<cstdio>#include<iostream>#include<cstdlib>#include<algorithm>#include<cstring>#include<queue>#include<stack>#include<vector>#include<cmath>#define ll long longusing namespace std;const int inf=0x3f3f3f3f;template <typename T>inline void _read(T& x){    char t=getchar();bool sign=true;    while(t<'0'||t>'9'){if(t=='-')sign=false;t=getchar();}    for(x=0;t>='0'&&t<='9';t=getchar())x=x*10+t-'0';    if(!sign)x=-x;}int n,m,e;int vistime;int father[100005],size[100005],son[100005],dep[100005],id[100005],top[100005];struct line{int to;line(){}line(int y){to=y;}};line edge[200005];int last[100005],_next[200005];void add_edge(int x,int y){edge[++e]=line(y);_next[e]=last[x];last[x]=e;}void dfs(int x,int fa,int depth){int i,v;int temp=0,maxson=0;father[x]=fa;dep[x]=depth;size[x]=1;for(i=last[x];i;i=_next[i]){v=edge[i].to;if(v==fa)continue;dfs(v,x,depth+1);size[x]+=size[v];if(size[v]>temp){temp=size[v];maxson=v;}}son[x]=maxson;}void dfs2(int x,int anc){int i,v;id[x]=++vistime;top[x]=anc;if(son[x])dfs2(son[x],anc);for(i=last[x];i;i=_next[i]){v=edge[i].to;if(v!=son[x]&&v!=father[x])dfs2(v,v);}}struct node{int x,y,z;node(){}node(int X,int Y,int Z){x=X;y=Y;z=Z;}};node q[200005];struct tree_node{int a,b;priority_queue<int> q1,q2;void push1(int x){q1.push(x);}void push2(int x){q2.push(x);}int top(){while(q1.size()&&q2.size()&&q1.top()==q2.top()){q1.pop();q2.pop();}if(q1.size())return q1.top();else return -1;}};tree_node tree[400005];void build(int p,int x,int y){tree[p].a=x;tree[p].b=y;if(x<y){int mid=(x+y)>>1;build((p<<1),x,mid);build((p<<1)+1,mid+1,y);}}int ty,val;void modify(int p,int x,int y){if(tree[p].b<x||tree[p].a>y)return;if(tree[p].a>=x&&tree[p].b<=y){if(ty==1)tree[p].push1(val);else tree[p].push2(val);return;}modify((p<<1),x,y);modify((p<<1)+1,x,y);}int tot;struct Sec{int l,r;Sec(){}Sec(int L,int R){l=L;r=R;}friend bool operator < (Sec A,Sec B){if(A.l==B.l)return A.r<B.r;else return A.l<B.l;}};Sec sec[100005];void change(int x,int y,int z){int i,pos=0;tot=0;while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]])swap(x,y);sec[++tot]=Sec(id[top[x]],id[x]);x=father[top[x]];}if(dep[x]>dep[y])swap(x,y);sec[++tot]=Sec(id[x],id[y]);sort(sec+1,sec+1+tot);val=z;for(i=1;i<=tot;i++){if(pos+1<=sec[i].l-1)modify(1,pos+1,sec[i].l-1);pos=sec[i].r;}if(pos<n)modify(1,pos+1,n);}int ans;void query(int p,int pos){if(tree[p].b<pos||tree[p].a>pos)return;if(tree[p].a<=pos&&tree[p].b>=pos){ans=max(ans,tree[p].top());}if(tree[p].a==tree[p].b)return;query((p<<1),pos);query((p<<1)+1,pos);}int main_main(){//freopen("temp.out","w",stdout);int i,j,k;cin>>n>>m;for(i=1;i<n;i++){int x,y;_read(x);_read(y);add_edge(x,y);add_edge(y,x);}dfs(1,0,1);dfs2(1,1);build(1,1,n);for(i=1;i<=m;i++){int op,x,y,z;_read(op);if(op==0){_read(x);_read(y);_read(z);q[i]=node(x,y,z);ty=1;change(x,y,z);}else if(op==1){_read(x);ty=2;change(q[x].x,q[x].y,q[x].z);}else {ans=-1;_read(x);query(1,id[x]);cout<<ans<<endl;}}}const int main_stack=16;  char my_stack[128<<20];  int main() {    __asm__("movl %%esp, (%%eax);\n"::"a"(my_stack):"memory");    __asm__("movl %%eax, %%esp;\n"::"a"(my_stack+sizeof(my_stack)-main_stack):"%esp");    main_main();    __asm__("movl (%%eax), %%esp;\n"::"a"(my_stack):"%esp");    return 0;  } 


0 0
原创粉丝点击