[CSTC2008] 网络管理

Posted wfj_2048

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CSTC2008] 网络管理相关的知识,希望对你有一定的参考价值。

题目描述 Description

M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门。为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络。该网络的结构由N个路由器和N-1条高速光缆组成。每个部门都有一个专属的路由器,部门局域网内的所有机器都联向这个路由器,然后再通过这个通信子网与其他部门进行通信联络。该网络结构保证网络中的任意两个路由器之间都存在一条直接或间接路径以进行通信。

 高速光缆的数据传输速度非常快,以至于利用光缆传输的延迟时间可以忽略。但是由于路由器老化,在这些路由器上进行数据交换会带来很大的延迟。而两个路由器之间的通信延迟时间则与这两个路由器通信路径上所有路由器中最大的交换延迟时间有关。作为M公司网络部门的一名实习员工,现在要求你编写一个简单的程序来监视公司的网络状况。该程序能够随时更新网络状况的变化信息(路由器数据交换延迟时间的变化),并且根据询问给出两个路由器通信路径上延迟第k大的路由器的延迟时间。

你的程序从输入文件中读入N个路由器和N-1条光缆的连接信息,每个路由器初始的数据交换延迟时间Ti,以及Q条询问(或状态改变)的信息。并依次处理这Q条询问信息,它们可能是:

1.        由于更新了设备,或者设备出现新的故障,使得某个路由器的数据交换延迟时间发生了变化。

2.        查询某两个路由器a和b之间的路径上延迟第k大的路由器的延迟时间。

输入描述 Input Description

输入文件network.in中的第一行为两个整数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大的路由器的延迟时间。注意a可以等于b,此时路径上只有一个路由器。

输出描述 Output Description

输出文件为network.out。对于每一个第二种询问(k>0),输出一行。包含一个整数为相应的延迟时间。如果路径上的路由器不足k个,则输出信息“invalid request!”(全部小写不包含引号,两个单词之间有一个空格)。

样例输入 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!

数据范围及提示 Data Size & Hint

100% 测试数据满足 n<=80000,q<=30000 。任意一个路由器在任何时刻都满足延迟时间小于108。对于所有询问满足 。

40% 测试数据满足所有询问中1<=k<=5 ,且路由器的延迟时间不会发生变化。

10% 测试数据满足n,q<=8000 。

正解:树链剖分+树状数组套主席树。

Orzywj大神写了个整体二分,代码量比我小1kb,然后常数是我的1/6。。我太弱了,所以写了个naive的树链剖分+主席树。

(其实上面这个是O(nlog^4n)的算法,所以是复杂度的差别了。。然后我后来又改了一下,直接每次把主席树的log^2n个根结点集中起来计算第k大就行了。。看下面代码吧。。)

树上的单点修改,路径查询第k大,那么显然我们可以考虑主席树。首先树剖构好这棵树,然后修改的话就用主席树修改的套路。查询的时候只要二分答案,转化为log个区间里>mid的数的个数,然后二分判定一下,就能很方便地用主席树做了。

 

朴素O(nlog^4n)代码:

  1 //It is made by wfj_2048~
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <cstdio>
  7 #include <vector>
  8 #include <cmath>
  9 #include <queue>
 10 #include <stack>
 11 #include <map>
 12 #include <set>
 13 #define inf (1<<30)
 14 #define N (80010)
 15 #define il inline
 16 #define RG register
 17 #define ll long long
 18 #define lb(x) (x & -x)
 19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
 20 
 21 using namespace std;
 22 
 23 struct edge{ int nt,to; }g[2*N];
 24 struct node{ int k,a,b; }q[30010];
 25 struct data{ int l,r; }qq[20];
 26 
 27 int head[N],top[N],fa[N],son[N],dep[N],tid[N],size[N],last[N],a[N],w[N],hsh[N+30010],n,Q,sz,ssz,num,cnt,tot;
 28 int sum[200*N],ls[200*N],rs[200*N],rt[N];
 29 
 30 il int gi(){
 31     RG int x=0,q=1; RG char ch=getchar(); while ((ch<0 || ch>9) && ch!=-) ch=getchar();
 32     if (ch==-) q=-1,ch=getchar(); while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar(); return q*x;
 33 }
 34 
 35 il void insert(RG int from,RG int to){ g[++num]=(edge){head[from],to},head[from]=num; return; }
 36 
 37 il void dfs1(RG int x,RG int p){
 38     fa[x]=p,dep[x]=dep[p]+1,size[x]=1; RG int v;
 39     for (RG int i=head[x];i;i=g[i].nt){
 40     v=g[i].to; if (v==p) continue;
 41     dfs1(v,x); size[x]+=size[v];
 42     if (size[son[x]]<=size[v]) son[x]=v;
 43     }
 44     return;
 45 }
 46 
 47 il void dfs2(RG int x,RG int p,RG int anc){
 48     top[x]=anc,tid[x]=++cnt,w[cnt]=a[x];
 49     if (son[x]) dfs2(son[x],x,anc); RG int v;
 50     for (RG int i=head[x];i;i=g[i].nt){
 51     v=g[i].to; if (v==p || v==son[x]) continue;
 52     dfs2(v,x,v);
 53     }
 54     return;
 55 }
 56 
 57 il void update(RG int x,RG int &y,RG int l,RG int r,RG int v,RG int fg){
 58     sum[y=++sz]=sum[x]+fg,ls[y]=ls[x],rs[y]=rs[x];
 59     if (l==r) return; RG int mid=(l+r)>>1;
 60     if (v<=mid) update(ls[x],ls[y],l,mid,v,fg);
 61     else update(rs[x],rs[y],mid+1,r,v,fg);
 62     return;
 63 }
 64 
 65 il int query(RG int x,RG int l,RG int r,RG int v){
 66     if (l==r) return 0; RG int mid=(l+r)>>1;
 67     if (v<=mid) return query(ls[x],l,mid,v)+sum[rs[x]];
 68     else return query(rs[x],mid+1,r,v);
 69 }
 70 
 71 il void add(RG int x,RG int v,RG int fg){ for (;x<=n;x+=lb(x)) update(rt[x],rt[x],1,tot,v,fg); return; }
 72 
 73 il int find(RG int x,RG int key){ RG int res=0; for (;x;x-=lb(x)) res+=query(rt[x],1,tot,key); return res; }
 74 
 75 il void change(RG int x,RG int v){ add(tid[x],last[tid[x]],-1),add(tid[x],v,1),last[tid[x]]=v; return; }
 76 
 77 il int check(RG int key,RG int ssz,RG int k){
 78     RG int res=0;
 79     for (RG int i=1;i<=ssz;++i) res+=find(qq[i].r,key)-find(qq[i].l-1,key);
 80     return res<k;
 81 }
 82 
 83 il int Query(RG int u,RG int v,RG int k){
 84     RG int ssz=0,l=1,r=tot,mid,ans;
 85     while (top[u]!=top[v]){
 86     if (dep[top[u]]<dep[top[v]]) swap(u,v);
 87     qq[++ssz].l=tid[top[u]],qq[ssz].r=tid[u];
 88     u=fa[top[u]];
 89     }
 90     if (dep[u]>dep[v]) swap(u,v);
 91     qq[++ssz].l=tid[u],qq[ssz].r=tid[v];
 92     while (l<=r){
 93     mid=(l+r)>>1;
 94     if (check(mid,ssz,k)) ans=mid,r=mid-1;
 95     else l=mid+1;
 96     }
 97     return hsh[ans];
 98 }
 99 
100 il int lca(RG int u,RG int v){
101     while (top[u]!=top[v]){
102     if (dep[top[u]]<dep[top[v]]) swap(u,v);
103     u=fa[top[u]];
104     }
105     return dep[u]<dep[v] ? u : v;
106 }
107 
108 il void work(){
109     n=gi(),Q=gi(); RG int u,v; for (RG int i=1;i<=n;++i) hsh[++tot]=a[i]=gi();
110     for (RG int i=1;i<n;++i) u=gi(),v=gi(),insert(u,v),insert(v,u); dfs1(1,0),dfs2(1,0,1);
111     for (RG int i=1;i<=Q;++i){ q[i].k=gi(),q[i].a=gi(),q[i].b=gi(); if (!q[i].k) hsh[++tot]=q[i].b; }
112     sort(hsh+1,hsh+tot+1),tot=unique(hsh+1,hsh+tot+1)-hsh-1;
113     for (RG int i=1;i<=n;++i) w[i]=lower_bound(hsh+1,hsh+tot+1,w[i])-hsh,add(i,w[i],1),last[i]=w[i];
114     for (RG int i=1;i<=Q;++i){
115     if (!q[i].k) q[i].b=lower_bound(hsh+1,hsh+tot+1,q[i].b)-hsh,change(q[i].a,q[i].b); else{
116         if (dep[q[i].a]+dep[q[i].b]-2*dep[lca(q[i].a,q[i].b)]+1<q[i].k) printf("invalid request!\n");
117         else printf("%d\n",Query(q[i].a,q[i].b,q[i].k));
118     }
119     }
120     return;
121 }
122 
123 int main(){
124     File("network");
125     work();
126     return 0;
127 }

 

O(nlog^3n)代码(非递归似乎快一些??):

  1 //It is made by wfj_2048~
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <cstdlib>
  6 #include <cstdio>
  7 #include <vector>
  8 #include <cmath>
  9 #include <queue>
 10 #include <stack>
 11 #include <map>
 12 #include <set>
 13 #define inf (1<<30)
 14 #define N (80010)
 15 #define il inline
 16 #define RG register
 17 #define ll long long
 18 #define lb(x) (x & -x)
 19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
 20 
 21 using namespace std;
 22 
 23 struct edge{ int nt,to; }g[2*N];
 24 struct node{ int k,a,b; }q[30010];
 25 
 26 int head[N],top[N],fa[N],son[N],dep[N],tid[N],size[N],last[N],a[N],w[N],hsh[N+30010],n,Q,sz,num,cnt,tot;
 27 int sum[200*N],ls[200*N],rs[200*N],rt[N],q1[1010],q2[1010],sz1,sz2;
 28 
 29 il int gi(){
 30     RG int x=0,q=1; RG char ch=getchar(); while ((ch<0 || ch>9) && ch!=-) ch=getchar();
 31     if (ch==-) q=-1,ch=getchar(); while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar(); return q*x;
 32 }
 33 
 34 il void insert(RG int from,RG int to){ g[++num]=(edge){head[from],to},head[from]=num; return; }
 35 
 36 il void dfs1(RG int x,RG int p){
 37     fa[x]=p,dep[x]=dep[p]+1,size[x]=1; RG int v;
 38     for (RG int i=head[x];i;i=g[i].nt){
 39     v=g[i].to; if (v==p) continue;
 40     dfs1(v,x); size[x]+=size[v];
 41     if (size[son[x]]<=size[v]) son[x]=v;
 42     }
 43     return;
 44 }
 45 
 46 il void dfs2(RG int x,RG int p,RG int anc){
 47     top[x]=anc,tid[x]=++cnt,w[cnt]=a[x];
 48     if (son[x]) dfs2(son[x],x,anc); RG int v;
 49     for (RG int i=head[x];i;i=g[i].nt){
 50     v=g[i].to; if (v==p || v==son[x]) continue;
 51     dfs2(v,x,v);
 52     }
 53     return;
 54 }
 55 
 56 il void update(RG int x,RG int &y,RG int l,RG int r,RG int v,RG int fg){
 57     sum[y=++sz]=sum[x]+fg,ls[y]=ls[x],rs[y]=rs[x];
 58     if (l==r) return; RG int mid=(l+r)>>1;
 59     if (v<=mid) update(ls[x],ls[y],l,mid,v,fg);
 60     else update(rs[x],rs[y],mid+1,r,v,fg);
 61     return;
 62 }
 63 
 64 il int query(RG int x,RG int l,RG int r,RG int v){
 65     if (l==r) return 0; RG int mid=(l+r)>>1;
 66     if (v<=mid) return query(ls[x],l,mid,v)+sum[rs[x]];
 67     else return query(rs[x],mid+1,r,v);
 68 }
 69 
 70 il int query(RG int sz1,RG int sz2,RG int l,RG int r,RG int k){
 71     if (l==r) return l; RG int mid=(l+r)>>1,res=0;
 72     for (RG int i=1;i<=sz2;++i) res+=sum[rs[q2[i]]];
 73     for (RG int i=1;i<=sz1;++i) res-=sum[rs[q1[i]]];
 74     if (res<k){
 75     for (RG int i=1;i<=sz1;++i) q1[i]=ls[q1[i]];
 76     for (RG int i=1;i<=sz2;++i) q2[i]=ls[q2[i]];
 77     return query(sz1,sz2,l,mid,k-res);
 78     } else{
 79     for (RG int i=1;i<=sz1;++i) q1[i]=rs[q1[i]];
 80     for (RG int i=1;i<=sz2;++i) q2[i]=rs[q2[i]];
 81     return query(sz1,sz2,mid+1,r,k);
 82     }
 83 }
 84 
 85 il void add(RG int x,RG int v,RG int fg){ for (;x<=n;x+=lb(x)) update(rt[x],rt[x],1,tot,v,fg); return; }
 86 
 87 il void change(RG int x,RG int v){ add(tid[x],last[tid[x]],-1),add(tid[x],v,1),last[tid[x]]=v; return; }
 88 
 89 il int Query(RG int u,RG int v,RG int k){
 90     RG int sz1=0,sz2=0;
 91     while (top[u]!=top[v]){
 92     if (dep[top[u]]<dep[top[v]]) swap(u,v);
 93     for (RG int i=tid[top[u]]-1;i;i-=lb(i)) q1[++sz1]=rt[i];
 94     for (RG int i=tid[u];i;i-=lb(i)) q2[++sz2]=rt[i];
 95     u=fa[top[u]];
 96     }
 97     if (dep[u]>dep[v]) swap(u,v);
 98     for (RG int i=tid[u]-1;i;i-=lb(i)) q1[++sz1]=rt[i];
 99     for (RG int i=tid[v];i;i-=lb(i)) q2[++sz2]=rt[i];
100     return hsh[query(sz1,sz2,1,tot,k)];
101 }
102 
103 il int lca(RG int u,RG int v){
104     while (top[u]!=top[v]){
105     if (dep[top[u]]<dep[top[v]]) swap(u,v);
106     u=fa[top[u]];
107     }
108     return dep[u]<dep[v] ? u : v;
109 }
110 
111 il void work(){
112     n=gi(),Q=gi(); RG int u,v; for (RG int i=1;i<=n;++i) hsh[++tot]=a[i]=gi();
113     for (RG int i=1;i<n;++i) u=gi(),v=gi(),insert(u,v),insert(v,u); dfs1(1,0),dfs2(1,0,1);
114     for (RG int i=1;i<=Q;++i){ q[i].k=gi(),q[i].a=gi(),q[i].b=gi(); if (!q[i].k) hsh[++tot]=q[i].b; }
115     sort(hsh+1,hsh+tot+1),tot=unique(hsh+1,hsh+tot+1)-hsh-1;
116     for (RG int i=1;i<=n;++i) w[i]=lower_bound(hsh+1,hsh+tot+1,w[i])-hsh,add(i,w[i],1),last[i]=w[i];
117     for (RG int i=1;i<=Q;++i){
118     if (!q[i].k) q[i].b=lower_bound(hsh+1,hsh+tot+1,q[i].b)-hsh,change(q[i].a,q[i].b); else{
119         if (dep[q[i].a]+dep[q[i].b]-2*dep[lca(q[i].a,q[i].b)]+1<q[i].k) printf("invalid request!\n");
120         else printf("%d\n",Query(q[i].a,q[i].b,q[i].k));
121     }
122     }
123     return;
124 }
125 
126 int main(){
127     File("network");
128     work();
129     return 0;
130 }

 

以上是关于[CSTC2008] 网络管理的主要内容,如果未能解决你的问题,请参考以下文章

[cstc2021]wp

基于Jira的Scrum敏捷管理实战 | IDCF

CSTC 部分pwn wp

CSTC 部分pwn wp

CSTC 部分pwn wp

CSTC 部分pwn wp