zoukankan      html  css  js  c++  java
  • bzoj4538 [Hnoi2016]网络

    Description

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

    Input

      第一行两个正整数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发生故障时,未被影响的请求中重要度的最大值是多少?”注意可能有某个服务器自身与自身进行数据 交互的情况。

    Output

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

    树链剖分套线段树套堆维护树上区间最大值
    对于修改将路径对应的区间的补集插入或删除一个值,查询对应线段树的单点查询

    最坏时间复杂度O(nlog3n)

    #include<cstdio>
    #include<queue>
    #include<algorithm>
    const int N=100005;
    int es[N*2],enx[N*2],e0[N],ep=2;
    int dep[N],sz[N],son[N],fa[N],top[N],id[N],idp=1;
    int n,m;
    void f1(int w,int pa){
        fa[w]=pa;
        dep[w]=dep[pa]+1;
        sz[w]=1;
        for(int i=e0[w];i;i=enx[i]){
            int u=es[i];
            if(u!=pa){
                f1(u,w);
                sz[w]+=sz[u];
                if(sz[u]>sz[son[w]])son[w]=u;
            }
        }
    }
    void f2(int w,int tp){
        top[w]=tp;
        id[w]=idp++;
        if(son[w])f2(son[w],tp);
        for(int i=e0[w];i;i=enx[i]){
            int u=es[i];
            if(u!=fa[w]&&u!=son[w])f2(u,u);
        }
    }
    struct heap{
        std::priority_queue<int>m,d;
        inline void ins(int x){
            m.push(x);
        }
        inline void del(int x){
            d.push(x);
        }
        inline int max(){
            while(!d.empty()&&m.top()==d.top())m.pop(),d.pop();
            if(m.empty())return -1;
            return m.top();
        }
    }h[262144];
    int l,r,x;
    void ins(int w=1,int L=1,int R=131072){
        if(l<=L&&R<=r){
            h[w].ins(x);
            return;
        }
        int M=L+R>>1;
        if(l<=M)ins(w<<1,L,M);
        if(r>M)ins(w<<1^1,M+1,R);
    }
    void del(int w=1,int L=1,int R=131072){
        if(l<=L&&R<=r){
            h[w].del(x);
            return;
        }
        int M=L+R>>1;
        if(l<=M)del(w<<1,L,M);
        if(r>M)del(w<<1^1,M+1,R);
    }
    struct sg{int l,r;}ss[64];
    bool operator<(sg a,sg b){return a.l<b.l;}
    int sp;
    inline void Ins(int x,int y){
        sp=0;
        ss[sp++]=(sg){0,0};
        ss[sp++]=(sg){262145,262145};
        int a=top[x],b=top[y],c;
        while(a!=b){
            if(dep[a]<dep[b])c=a,a=b,b=c,c=x,x=y,y=c;
            ss[sp++]=(sg){id[a],id[x]};
            x=fa[a];a=top[x];
        }
        if(dep[x]<dep[y])ss[sp++]=(sg){id[x],id[y]};
        else ss[sp++]=(sg){id[y],id[x]};
        std::sort(ss,ss+sp);
        for(int i=1;i<sp;i++)if(ss[i-1].r+1<ss[i].l){
            l=ss[i-1].r+1;r=ss[i].l-1;
            ins();
        }
    }
    inline void Del(int x,int y){
        sp=0;
        ss[sp++]=(sg){0,0};
        ss[sp++]=(sg){262145,262145};
        int a=top[x],b=top[y],c;
        while(a!=b){
            if(dep[a]<dep[b])c=a,a=b,b=c,c=x,x=y,y=c;
            ss[sp++]=(sg){id[a],id[x]};
            x=fa[a];a=top[x];
        }
        if(dep[x]<dep[y])ss[sp++]=(sg){id[x],id[y]};
        else ss[sp++]=(sg){id[y],id[x]};
        std::sort(ss,ss+sp);
        for(int i=1;i<sp;i++)if(ss[i-1].r+1<ss[i].l){
            l=ss[i-1].r+1;r=ss[i].l-1;
            del();
        }
    }
    inline void getmax(int w){
        int a=-1,b;
        for(w=id[w]+131071;w;w>>=1){
            b=h[w].max();
            if(b>a)a=b;
        }
        printf("%d
    ",a);
    }
    int qa[N*2],qb[N*2],qv[N*2];
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1,a,b;i<n;i++){
            scanf("%d%d",&a,&b);
            es[ep]=b;enx[ep]=e0[a];e0[a]=ep++;
            es[ep]=a;enx[ep]=e0[b];e0[b]=ep++;
        }
        f1(1,0);f2(1,1);
        for(int i=1;i<=m;i++){
            int op,a,b,v;
            scanf("%d",&op);
            if(op==0){
                scanf("%d%d%d",&a,&b,&v);
                qa[i]=a;qb[i]=b;qv[i]=v;
                x=v;
                Ins(a,b);
            }else if(op==1){
                scanf("%d",&a);
                x=qv[a];
                Del(qa[a],qb[a]);
            }else{
                scanf("%d",&v);
                getmax(v);
            }
        }
        return 0;
    }
  • 相关阅读:
    网页打开本地exe程序
    【JS】最简单的域名防红方法,QQ/微信打开网站提示浏览器打开
    【HTML】建站成功默认页面
    python中日志器的使用
    python中连接mysql
    python中处理配置文件
    接口实战项目总结上
    布隆过滤器和LRU Cache
    Python版常见的排序算法
    LeetCode 27. 移除元素
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5427474.html
Copyright © 2011-2022 走看看