zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Randomization Tests
    关于Spring中的<context:annotationconfig/>配置
    PUT method support
    在对话框picture control中利用opengl进行绘图
    【学习笔记】《卓有成效的管理者》 第三章 我能贡献什么
    程序员的黄金时代
    nginx webdav配置
    iphone4s 如何强制关机
    并查集
    实战虚拟化存储设计之三MultiPathing
  • 原文地址:https://www.cnblogs.com/Jackpei/p/12216517.html
Copyright © 2011-2022 走看看