zoukankan      html  css  js  c++  java
  • BZOJ1146: [CTSC2008]网络管理Network

    题解:查询带修树链上的第K大 我们可以树链剖分后 用主席树+树状数组维护序列即可 空间(nlog^2n) 时间(nlog^2n)

    /**************************************************************
        Problem: 1146
        User: c20161007
        Language: C++
        Result: Accepted
        Time:5264 ms
        Memory:202320 kb
    ****************************************************************/
     
    #include <algorithm>
    #include <iostream>
    #include <vector>
    #include <cstdio>
    const int MAXN=8e4+10;
    using namespace std;
    using namespace std;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return f*x;
    }
    int n,m,q;int key[MAXN],son[MAXN],num[MAXN],dep[MAXN],fa[MAXN],tp[MAXN],p[MAXN],fp[MAXN];
    int rt[MAXN];
    int cnt,cnt1,ans;
    typedef struct node{
        int l,r,sum;
    }node;
    node d[205*MAXN];
    vector<int>vec[MAXN];
    vector<int>qko1,qko2;
    vector<int>V1,V2;
    vector<int>v1;
    void dfs(int v,int pre,int deep){
        num[v]=1;dep[v]=deep+1;fa[v]=pre;
        for(int i=0;i<vec[v].size();i++){
        if(vec[v][i]!=pre){
            dfs(vec[v][i],v,deep+1);
            num[v]+=num[vec[v][i]];
            if(son[v]==-1||num[vec[v][i]]>num[son[v]])son[v]=vec[v][i];
        }
        }
    }
    void dfs1(int v,int td){
        p[v]=++cnt;fp[p[v]]=v;tp[v]=td;
        if(son[v]!=-1)dfs1(son[v],td);
        for(int i=0;i<vec[v].size();i++){
        if(vec[v][i]!=son[v]&&vec[v][i]!=fa[v])dfs1(vec[v][i],vec[v][i]);
        }
    }
    void update(int &x,int y,int l,int r,int t,int vul){
        x=++cnt1;d[x]=d[y];d[x].sum+=vul;
        if(l==r)return ;
        int mid=(l+r)>>1;
        if(t<=mid)update(d[x].l,d[y].l,l,mid,t,vul);
        else update(d[x].r,d[x].r,mid+1,r,t,vul);
    }
    int querty(int l,int r,int t){
         if(l==r)return l;
         int k=0;int mid=(l+r)>>1;
         for(int i=0;i<qko2.size();i++)k+=d[d[qko2[i]].l].sum;
         for(int i=0;i<qko1.size();i++)k-=d[d[qko1[i]].l].sum;
         if(t<=k){
        for(int i=0;i<qko2.size();i++)qko2[i]=d[qko2[i]].l;
        for(int i=0;i<qko1.size();i++)qko1[i]=d[qko1[i]].l;
        return querty(l,mid,t);
         }
         else{
        for(int i=0;i<qko2.size();i++)qko2[i]=d[qko2[i]].r;
        for(int i=0;i<qko1.size();i++)qko1[i]=d[qko1[i]].r;
        return querty(mid+1,r,t-k);
         }
    }
    int get_id(int x){return x&(-x);}
    int slove(int u,int v,int k){
        int uu=tp[u];int vv=tp[v];int num=0;
        V1.clear();V2.clear();qko1.clear();qko2.clear();
        while(uu!=vv){
        if(dep[uu]<dep[vv])swap(uu,vv),swap(u,v);
        V2.push_back(p[u]);
        if(p[uu]!=1)V1.push_back(p[uu]-1);
        num+=dep[u]-dep[uu]+1;u=fa[uu];uu=tp[u];
        }
        if(dep[u]>dep[v])swap(u,v);
        num+=dep[v]-dep[u]+1;
        if(num<k)return -1;
        if(p[u]!=1)V1.push_back(p[u]-1);
        V2.push_back(p[v]);
        for(int i=0;i<V1.size();i++){
        for(int j=V1[i];j>0;j-=get_id(j))qko1.push_back(rt[j]);
        }
        for(int i=0;i<V2.size();i++){
        for(int j=V2[i];j>0;j-=get_id(j))qko2.push_back(rt[j]);
        }
        return querty(1,q,num-k+1);
    }
    void Update(int v,int vul,int op){
        V1.clear();
        for(int i=p[v];i<=n;i+=get_id(i))V1.push_back(i);
        if(op==0)for(int i=0;i<V1.size();i++)update(rt[V1[i]],rt[V1[i]],1,q,key[v],-1);
        for(int i=0;i<V1.size();i++)update(rt[V1[i]],rt[V1[i]],1,q,vul,1);
        key[v]=vul;
    }
    typedef struct Node{
        int op,u,v;
    }Node;
    Node que[MAXN];
    int main(){
        n=read();m=read();int u,v,op;q=n+m;
        for(int i=1;i<=n;i++)son[i]=-1;
        for(int i=1;i<=n;i++)key[i]=read(),v1.push_back(key[i]);
        for(int i=1;i<n;i++)u=read(),v=read(),vec[u].push_back(v),vec[v].push_back(u);
        dfs(1,0,0);
        dfs1(1,1);
        for(int i=1;i<=m;i++){
        que[i].op=read(),que[i].u=read(),que[i].v=read();
        if(que[i].op==0)v1.push_back(que[i].v);
        }
        sort(v1.begin(),v1.end());
        int sz=unique(v1.begin(),v1.end())-v1.begin();
        for(int i=1;i<=n;i++)key[i]=lower_bound(v1.begin(),v1.begin()+sz,key[i])-v1.begin()+1;
        for(int i=1;i<=n;i++)Update(i,key[i],1);
        for(int i=1;i<=m;i++){
        //que[i].v=lower_bound(v1.begin(),v1.begin()+sz,que[i].v)-v1.begin()+1;
        if(!que[i].op){que[i].v=lower_bound(v1.begin(),v1.begin()+sz,que[i].v)-v1.begin()+1;;Update(que[i].u,que[i].v,0);}
        else {
            int res=slove(que[i].u,que[i].v,que[i].op);
            if(res==-1)puts("invalid request!");
            else printf("%d
    ",v1[res-1]);
        }
        }
        return 0;
    }
    

     
                      1146: [CTSC2008]网络管理Network
                      Time Limit: 50 Sec  Memory Limit: 256 MB
                      Submit: 4275  Solved: 1306
                      [Submit][Status][Discuss]
    Description
      M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门。为了让分布在世界各地的N个
    部门之间协同工作,公司搭建了一个连接整个公司的通信网络。该网络的结构由N个路由器和N-1条高速光缆组成。
    每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部
    门进行通信联络。该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信。 高速光
    缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略。但是由于路由器老化,在这些路由器上进行
    数据交换会带来很大的延迟。而两个路由器之间的通信延迟时间则与这两个路由器通信路径上所有路由器中最大的
    交换延迟时间有关。作为M公司网络部门的一名实习员工,现在要求你编写一个简单的程序来监视公司的网络状况
    。该程序能够随时更新网络状况的变化信息(路由器数据交换延迟时间的变化),并且根据询问给出两个路由器通
    信路径上延迟第k大的路由器的延迟时间。【任务】 你的程序从输入文件中读入N个路由器和N-1条光缆的连接信息
    ,每个路由器初始的数据交换延迟时间Ti,以及Q条询问(或状态改变)的信息。并依次处理这Q条询问信息,它们
    可能是: 1. 由于更新了设备,或者设备出现新的故障,使得某个路由器的数据交换延迟时间发生了变化。 2. 查
    询某两个路由器a和b之间的路径上延迟第k大的路由器的延迟时间。
    Input
    第一行为两个整数N和Q,分别表示路由器总数和询问的总数。
    第二行有N个整数,第i个数表示编号为i的路由器初始的数据延迟时间Ti。
    紧接着N-1行,每行包含两个整数x和y。表示有一条光缆连接路由器x和路由器y。
    紧接着是Q行,每行三个整数k、a、b。
    如果k=0,则表示路由器a的状态发生了变化,它的数据交换延迟时间由Ta变为b
    如果k>0,则表示询问a到b的路径上所经过的所有路由器(包括a和b)中延迟
    第k大的路由器的延迟时间。
    注意N,Q<=80000,任意一个路由器在任何时刻都满足延迟时间小于10^8。
    对于所有询问满足0<=K<=N
    Output
    对于每一个第二种询问(k>0),输出一行。包含一个整数为相应的延迟时间。
    如果路径上的路由器不足k个,则输出信息“invalidrequest!”
    (全部小写不包含引号,两个单词之间有一个空格)。
    Sample Input
    5 5

    5 1 2 3 4

    3 1

    2 1

    4 3

    5 3

    2 4 5

    0 1 2

    2 2 3

    2 1 4

    3 3 5

    Sample Output
    3

    2

    2

    invalid request!

  • 相关阅读:
    比较一下ASP、ASP.net、JSP和PHP的优点和缺点
    修改MSSQLServer的登陆方式
    ASP.NET获取IP和MAC代码(C#)
    RPM 五种基本的操作方式
    飞鸽TCP/IP 10106错误解决
    修复rpm命令(不小心删了rpm命令)方法
    Asp.Net连接ACCESS数据库相对路径问题 web.config中如何使用相对路径及在类文件中调用这个相对路径
    VMware下redhat linux 9使用NAT共享主机IP上网
    Visual Studio2005 + Visual SourceSafe 2005 实现团队开发、源代码管理、版本控制
    SQL2005安装出现“性能监视器计数器要求错误”的解决方案
  • 原文地址:https://www.cnblogs.com/wang9897/p/9426100.html
Copyright © 2011-2022 走看看