Luogu P4175 [CTSC2008]网络管理

Posted jackpei

tags:

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

dfs序上的带修主席树;求链上的信息仍然是四个点差分,只不过求前缀和变成了 (log) 的树状数组;

#include<cstdio>
#include<iostream>
#include<algorithm>
#define R register int
using namespace std;
namespace Luitaryi {
char B[1<<15],*S=B,*T=B;
#define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
inline int g() { R x=0,f=1;
  register char s; while(!isdigit(s=getchar())) f=s=='-'?-1:f;
  do x=x*10+(s^48); while(isdigit(s=getchar())); return x*f;
} const int N=80010,D=125;
int n,q,c[N],b[N<<1];
int vr[N<<1],nxt[N<<1],fir[N],cnt;
int dfn[N],low[N],son[N],d[N],pre[N],sz[N],top[N],tim;
int ls[N*D],rs[N*D],sum[N*D],rt[N],L;
struct node {int op,u,v;}a[N];
inline void add(int u,int v) {
  vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;
  vr[++cnt]=u,nxt[cnt]=fir[v],fir[v]=cnt;
}
inline void dfs(int u) {
  dfn[u]=++tim; sz[u]=1;
  for(R i=fir[u];i;i=nxt[i]) {
    R v=vr[i];
    if(d[v]) continue;
    d[v]=d[u]+1,pre[v]=u;
    dfs(v);
    if(sz[son[u]]<sz[v]) son[u]=v;
  } low[u]=tim;
}
inline void dfs2(int u,int tp) {
  top[u]=tp;
  if(son[u]) dfs2(son[u],tp);
  for(R i=fir[u];i;i=nxt[i]) {
    R v=vr[i];
    if(v!=son[u]&&v!=pre[u]) dfs2(v,v);
  }
}
inline int lca(int u,int v) {
  while(top[u]!=top[v]) {
    if(d[top[u]]<d[top[v]]) swap(u,v);
    u=pre[top[u]];
  } return d[u]<d[v]?u:v;
}
inline void change(int& tr,int l,int r,int p,int d) {
  if(!tr) tr=++cnt; sum[tr]+=d;
  if(l==r) return ; R md=(l+r)>>1;
  p<=md?change(ls[tr],l,md,p,d):change(rs[tr],md+1,r,p,d);
}
int m0[31],m1[31];
inline int query(int l,int r,int k) {
  if(l==r) return l;
  R md=(l+r)>>1,tmp=0;
  for(R i=1;i<=m0[0];++i) tmp+=sum[ls[m0[i]]];
  for(R i=1;i<=m1[0];++i) tmp-=sum[ls[m1[i]]];
  if(k<=tmp) {
    for(R i=1;i<=m0[0];++i) m0[i]=ls[m0[i]];
    for(R i=1;i<=m1[0];++i) m1[i]=ls[m1[i]];
    return query(l,md,k);
  } else {
    for(R i=1;i<=m0[0];++i) m0[i]=rs[m0[i]];
    for(R i=1;i<=m1[0];++i) m1[i]=rs[m1[i]];
    return query(md+1,r,k-tmp);
  }
}
inline void change(int x,int v,int op) {
  for(;x<=n;x+=x&-x) change(rt[x],1,L,v,op);
}
inline void main() {
  n=g(),q=g();
  for(R i=1;i<=n;++i) b[i]=c[i]=g();
  for(R i=1,u,v;i<n;++i) 
    u=g(),v=g(),add(u,v);
  d[1]=1; dfs(1),dfs2(1,1),L=n;
  for(R i=1;i<=q;++i) {
    a[i].op=g(),a[i].u=g(),a[i].v=g();
    if(!a[i].op) b[++L]=a[i].v;
  }
  sort(b+1,b+L+1),L=unique(b+1,b+L+1)-b-1;
  for(R i=1;i<=n;++i) c[i]=lower_bound(b+1,b+L+1,c[i])-b;
  for(R i=1;i<=n;++i) change(dfn[i],c[i],1),change(low[i]+1,c[i],-1);
  for(R i=1,op,u,v,l,fl,tmp;i<=q;++i) {
    op=a[i].op,u=a[i].u,v=a[i].v;
    if(op) {
      l=lca(u,v),fl=pre[l];
      tmp=d[u]+d[v]-d[l]-d[fl];
      if(op>tmp) {puts("invalid request!"); continue;}
      m0[0]=m1[0]=0;
      for(R i=dfn[u];i;i-=i&-i) m0[++m0[0]]=rt[i];
      for(R i=dfn[v];i;i-=i&-i) m0[++m0[0]]=rt[i];
      for(R i=dfn[l];i;i-=i&-i) m1[++m1[0]]=rt[i];
      for(R i=dfn[fl];i;i-=i&-i) m1[++m1[0]]=rt[i];
      printf("%d
",b[query(1,L,tmp-op+1)]);
    } else {
      change(dfn[u],c[u],-1),change(low[u]+1,c[u],1);
      c[u]=lower_bound(b+1,b+L+1,v)-b;
      change(dfn[u],c[u],1),change(low[u]+1,c[u],-1);
    }
  }
}
} signed main() {Luitaryi::main(); return 0;}

2020.01.20

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

[CTSC2008]网络管理(整体二分+树剖+树状数组)

「CTSC2008」网络管理

[CTSC2008]网络管理

BZOJ1146CTSC2008网络管理

[CTSC2008]网络管理

[CTSC2008]网络管理