【BZOJ4538】【HNOI2016】网络

来源:互联网 发布:java使用odata 编辑:程序博客网 时间:2024/06/07 20:53

题目链接,我是真的懒得调题目的格式。。。

题解

树链剖分搞一下LCA
把线段树弄出来
这只是形式上的线段树
本质上是维护一段区间的一个堆
每次把堆插入节点,
询问的时候查询线段树上的堆的最大值就行了
但是在插入节点的时候
把节点插入到非当前树链剖分经过的节点中
这里要稍微处理一下。

#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;}
原创粉丝点击