zoukankan      html  css  js  c++  java
  • bzoj 4538: [Hnoi2016]网络

    Description

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

    solution

    正解:树链剖分+堆
    想了个log^8log^3的做法,题目要我们怎么处理,我们就怎么处理
    因为每一条路径只会被加入和删除一次,想到均摊复杂度的做法,我们在线段树的每一个节点上套一个堆.
    对于一条路径,我们把没有在路径上的点,加入到线段树对应节点上的堆中去即可
    对于加入的方法:因为树链剖分抠出的区间是一个个不相交的区间,我们抠出来排一个序,然后修改没有被覆盖到的区域即可,因为区间个数是log的,所以是对的.
    区间修改时标记永久化,每一条路径只会被加入log个堆中,这样空间复杂度就成了 (O(nlogn)) 的了.

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=100005,M=200005;
    inline int gi(){
      RG int str=0;RG char ch=getchar();
      while(ch>'9' || ch<'0')ch=getchar();
      while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
      return str;
    }
    int head[N],nxt[N<<1],to[N<<1],num=0,n,m,dep[N],fa[N];
    void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
    int sz[N],son[N],top[N],id[N],DFN=0;bool d[M];
    inline void dfs1(int x){
      sz[x]=1;
      for(int i=head[x];i;i=nxt[i]){
        int u=to[i];if(dep[u])continue;
        dep[u]=dep[x]+1;fa[u]=x;
        dfs1(u);
        sz[x]+=sz[u];
        if(sz[u]>=sz[son[x]])son[x]=u;
      }
    }
    inline void dfs2(int x,int tp){
      id[x]=++DFN;top[x]=tp;
      if(son[x])dfs2(son[x],tp);
      for(int i=head[x];i;i=nxt[i]){
        int u=to[i];
        if(u!=fa[x] && u!=son[x])dfs2(u,u);
      }
    }
    #define ls (o<<1)
    #define rs (o<<1|1)
    struct node{
      int x,id;
      node(){}
      node(int _x,int _id){x=_x;id=_id;}
      bool operator <(const node &pr)const{return x<pr.x;}
    };
    priority_queue<node>q[N<<2];int NOWID=0;
    inline void Modify(int l,int r,int o,int sa,int se,int t){
      if(l>se || r<sa)return ;
      if(sa<=l && r<=se){
        q[o].push(node(t,NOWID));
        return ;
      }
      int mid=(l+r)>>1;
      Modify(l,mid,ls,sa,se,t);Modify(mid+1,r,rs,sa,se,t);
    }
    int tot=0;
    struct Line{
      int l,r;
      bool operator <(const Line &pr)const{
        return l<pr.l;
      }
    }st[N];
    inline void updata(int x,int y,int z){
      tot=0;
      while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        st[++tot].l=id[top[x]];st[tot].r=id[x];
        x=fa[top[x]];
      }
      if(id[x]>id[y])swap(x,y);
      st[++tot].l=id[x];st[tot].r=id[y];
    
      sort(st+1,st+tot+1);
      int last=1;
      for(int i=1;i<=tot;i++){
        if(last<st[i].l)Modify(1,n,1,last,st[i].l-1,z);
        last=st[i].r+1;
      }
      if(last<=n)Modify(1,n,1,last,n,z);
    }
    inline int qry(int l,int r,int o,int sa){
      int mid=(l+r)>>1,ret=0;
      if(l!=r){
        if(sa<=mid)ret=qry(l,mid,ls,sa);
        else ret=qry(mid+1,r,rs,sa);
      }
      while(!q[o].empty()){
        node p=q[o].top();
        if(!d[p.id]){ret=Max(ret,p.x);break;}
        q[o].pop();
      }
      return ret;
    }
    void work()
    {
      int x,y,z,op;
      n=gi();m=gi();
      for(int i=1;i<n;i++){
        x=gi();y=gi();
        link(x,y);link(y,x);
      }
      dep[1]=1;dfs1(1);dfs2(1,1);
      for(int i=1;i<=m;i++){
        op=gi();x=gi();NOWID=i;
        if(op==0){y=gi();z=gi();updata(x,y,z);}
        else if(op==1)d[x]=1;
        else{
          int tmp=qry(1,n,1,id[x]);
          if(!tmp)puts("-1");
          else printf("%d
    ",tmp);
        }
      }
    }
    
    int main()
    {
      work();
      return 0;
    }
    
    
  • 相关阅读:
    用Shell判断字符串包含关系
    shell命令调用http接口(curl方式)
    shell脚本实现发送信息到钉钉
    功能测试特殊字符处理总结
    Java_Swing实现小球沿正弦曲线运动的代码
    Python迁移MySQL数据到MongoDB脚本
    1. WP8.1学习笔记
    0. WP8.1学习笔记
    小练习--低仿系统计算器
    C#字符串题目
  • 原文地址:https://www.cnblogs.com/Yuzao/p/7965882.html
Copyright © 2011-2022 走看看