zoukankan      html  css  js  c++  java
  • BZOJ 4129 Haruna’s Breakfast

    传送门

    同样是树上莫队

    只不过要求一个集合的mex,这里可以使用分块,可以在根号时间内得出解

    /**************************************************
        Problem: 4129
        User: star_magic_young
        Language: C++
        Result: Accepted
        Time:748 ms
        Memory:8712 kb
    ****************************************************/
     
    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
     
    using namespace std;
    const int N=50000+10;
    il int rd()
    {
      int x=0,w=1;char ch=0;
      while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
      while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
      return x*w;
    }
    int n,m,q,szm,mm[N],ti,mdf[N][3],a[N];
    int na,an[N];
    int to[N<<1],nt[N<<1],hd[N],tot=1,st[N],tp,fa[N],sz[N],de[N],son[N],top[N];
    bool v[N];
    il void add(int x,int y)
    {
      ++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
      ++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
    }
    void dfs1(int x)
    {
      sz[x]=1;
      int la=tp;
      for(int i=hd[x];i;i=nt[i])
        {
          int y=to[i];
          if(y==fa[x]) continue;
          fa[y]=x,de[y]=de[x]+1,dfs1(y),sz[x]+=sz[y];
          if(sz[son[x]]<sz[y]) son[x]=y;
          if(tp-la>=szm){++m;while(tp!=la) mm[st[tp--]]=m;}
        }
      st[++tp]=x;
    }
    void dfs2(int x,int ntp)
    {
      top[x]=ntp;
      if(son[x]) dfs2(son[x],ntp);
      for(int i=hd[x];i;i=nt[i])
        {
          int y=to[i];
          if(y==fa[x]||y==son[x]) continue;
          dfs2(y,y);
        }
    }
    il int glca(int x,int y)
    {
      while(top[x]!=top[y])
        {
          if(de[top[x]]<de[top[y]]) swap(x,y);
          x=fa[top[x]];
        }
      return de[x]<de[y]?x:y;
    }
     
    int b[N],sm[400],ll[400],rr[400],sq,tt=-1;
    il void upd(int x)
    {
      v[x]^=1;
      if(a[x]<=n)
        {
          if(v[x]) sm[a[x]/sq]+=(++b[a[x]]==1);
          else sm[a[x]/sq]-=(--b[a[x]]==0);
        }
    }
    il int gans()
    {
      for(int i=0;i<=tt;++i)
        if(sm[i]!=rr[i]-ll[i]+1)
          {
            for(int j=ll[i];j<=rr[i];++j)
              if(!b[j]) return j;
          }
      return 1******7;
    }
    il void mv(int x,int y)
    {
      if(x==y) return;
      if(de[x]<de[y]) swap(x,y);
      while(de[x]>de[y])
        {
          upd(x),x=fa[x];
        }
      while(x!=y)
        {
          upd(x),x=fa[x];
          upd(y),y=fa[y];
        }
      //upd(x);
    }
    struct qu
    {
      int l,r,t,id;
      bool operator < (const qu &bb) const {return mm[l]!=mm[bb.l]?mm[l]<mm[bb.l]:(mm[r]!=mm[bb.r]?mm[r]<mm[bb.r]:t<bb.t);}
    }qq[N];
     
    int main()
    {
      n=rd(),q=rd();
      szm=(int)pow(n,0.45);
      sq=sqrt(n);
      for(int i=0;i<=n;i+=sq) ll[++tt]=i,rr[tt]=i+sq-1;
      rr[tt]=min(rr[tt],n);
      for(int i=1;i<=n;++i) a[i]=rd();
      for(int i=1;i<n;++i) add(rd(),rd());
      dfs1(1);
      ++m;while(tp) mm[st[tp--]]=m;
      dfs2(1,1);
      for(int i=1;i<=q;++i)
        {
          int op=rd();
          if(op)
            {
              qq[i-ti].l=rd(),qq[i-ti].r=rd(),qq[i-ti].t=ti,qq[i-ti].id=i-ti;
              if(mm[qq[i-ti].l]>mm[qq[i-ti].r]) swap(qq[i-ti].l,qq[i-ti].r);
            }
          else mdf[++ti][0]=rd(),mdf[ti][1]=rd();
        }
      sort(qq+1,qq+q-ti+1);
      for(int i=1,l=1,r=1,t=0;i<=q-ti;l=qq[i].l,r=qq[i].r,++i)
        {
          while(t<qq[i].t)
            {
              ++t;
              int xx=mdf[t][0],yy=mdf[t][1];mdf[t][2]=a[xx];
              if(v[xx])
                {
                  if(a[xx]<=n) sm[a[xx]/sq]-=(--b[a[xx]]==0);
                  if(yy<=n) sm[yy/sq]+=(++b[yy]==1);
                }
              a[xx]=yy;
            }
          while(t>qq[i].t)
            {
              int xx=mdf[t][0],yy=mdf[t][2];
              if(v[xx]) 
                {
                  if(a[xx]<=n) sm[a[xx]/sq]-=(--b[a[xx]]==0);
                  if(yy<=n) sm[yy/sq]+=(++b[yy]==1);
                }
              a[xx]=yy;
              --t;
            }
          mv(l,qq[i].l),mv(r,qq[i].r);
          int lca=glca(qq[i].l,qq[i].r);
          upd(lca),an[qq[i].id]=gans(),upd(lca);
        }
      for(int i=1;i<=q-ti;++i) printf("%d
    ",an[i]);
      return 0;
    }
    
  • 相关阅读:
    java设计模式之适配器模式
    在Eclipse中建立Maven Web项目
    java设计模式之原型模式
    java设计模式之建造者模式
    java设计模式之工厂模式
    java设计模式之单例模式
    C# 前端多次上传文件
    C# async 和 await
    .NET 4.0 任务(Task)
    C# 5.0
  • 原文地址:https://www.cnblogs.com/smyjr/p/10059393.html
Copyright © 2011-2022 走看看