题解 P3250 【[HNOI2016]网络】

yybyyb

2017-10-04 15:49:57

Solution

这题真是相当的暴力。。。 树链剖分搞出DFS序,以及用来求LCA 既然是不在这个节点上的最大值 那就把除了这个路径上的点之外的所有点全部丢到一个堆里面 具体的讲: 类似于线段树套一个堆??? 具体的实现还是看代码把。。。 [但是我就喜欢强行把博客插进来](http://www.cnblogs.com/cjyyb/p/7623995.html) ```cpp #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<set> #include<map> #include<queue> #include<vector> #define MAX 110000 #define lson (now<<1) #define rson (now<<1|1) using namespace std; inline int read() { int x=0,t=1;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } struct Line { int v,next; }e[MAX*2]; struct Link { int l,r; }li[MAX]; struct Record { int u,v,w; }tt[MAX]; inline bool operator <(Link a,Link b) { if(a.l!=b.l)return a.l<b.l; else return a.r<b.r; } int size[MAX],hson[MAX]; int h[MAX],cnt=1,dep[MAX],top[MAX],ff[MAX]; inline void Add(int u,int v) { e[cnt]=(Line){v,h[u]}; h[u]=cnt++; } struct PQ { priority_queue<int> Q1; priority_queue<int> Q2; void push(int x) { Q1.push(x); } void del(int x) { Q2.push(x); } int top() { while(!Q2.empty()&&Q1.top()==Q2.top()){Q1.pop();Q2.pop();} return Q1.empty()?-1:Q1.top(); } }t[MAX*5]; int tim,N,M,dfn[MAX]; void DFS1(int u,int f) { size[u]=1;dep[u]=dep[f]+1; for(int i=h[u];i;i=e[i].next) { int v=e[i].v; if(v==f)continue; ff[v]=u; DFS1(v,u); size[u]+=size[v]; if(size[v]>size[hson[u]])hson[u]=v; } } void DFS2(int u,int tp) { top[u]=tp;dfn[u]=++tim; if(hson[u])DFS2(hson[u],tp); for(int i=h[u];i;i=e[i].next) { int v=e[i].v; if(v==ff[u]||v==hson[u])continue; DFS2(v,v); } } void Update(int now,int l,int r,int al,int ar,int k,int opt) { if(al==l&&ar==r) { opt?t[now].del(k):t[now].push(k); return; } int mid=(l+r)>>1; if(ar<=mid)Update(lson,l,mid,al,ar,k,opt); else if(al>mid)Update(rson,mid+1,r,al,ar,k,opt); else{Update(lson,l,mid,al,mid,k,opt);Update(rson,mid+1,r,mid+1,ar,k,opt);} } int Query(int now,int l,int r,int x) { if(l==r)return t[now].top(); int mid=(l+r)>>1; int ans=t[now].top(); if(x<=mid)return max(ans,Query(lson,l,mid,x)); else return max(ans,Query(rson,mid+1,r,x)); } void Happen(int u,int v,int opt,int xx) { int qq=0; while(top[u]!=top[v]) { if(dep[top[u]]<dep[top[v]])swap(u,v); li[++qq]=(Link){dfn[top[u]],dfn[u]}; u=ff[top[u]]; } if(dep[u]<dep[v])swap(u,v); li[++qq]=(Link){dfn[v],dfn[u]}; sort(&li[1],&li[qq+1]); int Left=0; for(int i=1;i<=qq;Left=max(Left,li[i++].r)) if(Left+1<li[i].l)Update(1,1,N,Left+1,li[i].l-1,xx,opt); if(Left<N)Update(1,1,N,Left+1,N,xx,opt); } int main() { freopen("4538.in","r",stdin); N=read();M=read(); for(int i=1;i<N;++i) { int u=read(),v=read(); Add(u,v);Add(v,u); } DFS1(1,0);DFS2(1,1); for(int i=1;i<=M;++i) { int opt=read(); if(opt==2) { int x=read(); printf("%d\n",Query(1,1,N,dfn[x])); } else if(opt==1) { int r=read(); Happen(tt[r].u,tt[r].v,opt,tt[r].w); } else { tt[i]=(Record){read(),read(),read()}; Happen(tt[i].u,tt[i].v,opt,tt[i].w); } } return 0; } ```