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\n",an[i]);
  return 0;
}
posted @ 2018-12-03 16:49  ✡smy✡  阅读(153)  评论(0编辑  收藏  举报