• 【树上莫队】【带修莫队】【权值分块】bzoj1146 [CTSC2008]网络管理Network


    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define N 80001
    int v[N<<1],en,first[N],next[N<<1];
    void AddEdge(int U,int V)
    {
    	v[++en]=V;
    	next[en]=first[U];
    	first[U]=en;
    }
    struct Point{int p,v;}t[86000];
    bool operator < (Point a,Point b){return a.v<b.v;}
    int n,m,ma[86000],a[86000],zy,b[86000];
    int eq,ec,blo,sz,siz[N],top[N],fa[N],dep[N],num[N];
    void dfs(int U)
    {
    	for(int i=first[U];i;i=next[i])
    	  if(v[i]!=fa[U])
    	    {
    	      fa[v[i]]=U;
    	      dep[v[i]]=dep[U]+1;
    	      if(siz[top[U]]<sz)
    	        {
    	          ++siz[top[U]];
    	          top[v[i]]=top[U];
    	        }
    	      dfs(v[i]);
    	    }
    }
    void df2(int U)
    {
    	num[U]=blo;
    	for(int i=first[U];i;i=next[i])
    	  if(v[i]!=fa[U]&&top[v[i]]==top[U])
    	    df2(v[i]);
    }
    int lca(int U,int V)
    {
    	while(U!=V)
    	  {
    	  	if(top[U]!=top[V])
    	  	  {
    	  	  	if(dep[top[U]]<dep[top[V]])
    	  	  	  swap(U,V);
    	  	  	U=fa[top[U]];
    	  	  }
    	  	else
    	  	  {
    	  	  	if(dep[U]<dep[V])
    	  	  	  swap(U,V);
    	  	  	U=fa[U];
    	  	  }
    	  }
    	return U;
    }
    struct UPT{int x,y,z;}CH[N];
    struct ASK{int l,r,k,p,t;}Q[N];
    bool operator < (const ASK &a,const ASK &b)
    {
        if(num[a.l]==num[b.l])
          {
            if(num[a.r]==num[b.r])
              return a.t<b.t;
            return num[a.r]<num[b.r];
          }
        return num[a.l]<num[b.l];
    }
    int nu2[86000],r[300],sumv[300],bl2=1,T[86000];
    void makeblock()
    {
    	int sz=sqrt(zy); if(!sz) sz=0;
    	for(;bl2*sz<zy;++bl2)
    	  {
    	  	r[bl2]=bl2*sz;
    	  	for(int i=r[bl2-1]+1;i<=r[bl2];++i)
    	  	  nu2[i]=bl2;
    	  }
    	r[bl2]=zy;
    	for(int i=r[bl2-1]+1;i<=r[bl2];++i)
    	  nu2[i]=bl2;
    }
    void Update(int x,int op){T[x]+=op; sumv[nu2[x]]+=op;}
    bool vis[N];
    void Work(int U,int V,int LCA)
    {
        while(U!=LCA)
          {
            vis[U]^=1;
            Update(a[U],vis[U]?1:-1);
            U=fa[U];
          }
        while(V!=LCA)
          {
            vis[V]^=1;
            Update(a[V],vis[V]?1:-1);
            V=fa[V];
          }
    } 
    int Kth(int K)
    {
    	int cnt=0;
    	for(int i=bl2;i;--i)
    	  {
    	  	cnt+=sumv[i];
    	  	if(cnt>=K)
    	  	  {
    	  	  	cnt-=sumv[i];
    	  	  	for(int j=r[i];;--j)
    	  	  	  {
    	  	  	  	cnt+=T[j];
    	  	  	  	if(cnt>=K)
    	  	  	  	  return ma[j];
    	  	  	  }
    	  	  }
    	  }
    	return -1;
    }
    int Ks[N],anss[N];
    int main()
    {
    	int x,y;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i)
    	  {
    	  	scanf("%d",&t[i].v);
    	  	t[i].p=i;
    	  }
    	for(int i=1;i<n;++i)
    	  {
    	  	 scanf("%d%d",&x,&y);
    	  	 AddEdge(x,y);
    	  	 AddEdge(y,x);
    	  }
    	for(int i=1;i<=n;++i)
    	  {
    	  	top[i]=i;
    	  	siz[i]=1;
    	  }
    	sz=(int)pow((double)n,2.0/3.0);
    	dfs(1);
    	for(int i=1;i<=n;++i)
    	  if(top[i]==i)
    	    {
    	      ++blo;
    	      df2(i);
    	    }
    	en=n;
    	for(int i=1;i<=m;++i)
    	  {
    	  	scanf("%d",&Ks[i]);
    	  	if(!Ks[i])
    	  	  {
    	  	  	++ec; ++en;
    	  	  	scanf("%d%d",&CH[ec].x,&t[en].v);
    	  	  	t[en].p=en;
    	  	  }
    	  	else
    	  	  {
    	  	  	++eq;
    	  	  	Q[eq].k=Ks[i];
    	  	  	scanf("%d%d",&Q[eq].l,&Q[eq].r);
    	  	  	Q[eq].t=ec; Q[eq].p=eq;
    	  	  }
    	  }
    	sort(t+1,t+en+1);
        ma[a[t[1].p]=++zy]=t[1].v;
        for(int i=2;i<=en;++i)
          {
            if(t[i].v!=t[i-1].v) ++zy;
            ma[a[t[i].p]=zy]=t[i].v;
          }
        makeblock();
        memcpy(b,a,sizeof(int)*(n+1));
        en=n; ec=0;
        for(int i=1;i<=m;++i)
          if(!Ks[i])
          	{
          	  ++en; ++ec;
          	  CH[ec].y=a[en];
    		  CH[ec].z=b[CH[ec].x];
          	  b[CH[ec].x]=a[en];
          	}
        sort(Q+1,Q+eq+1);
    	for(int i=1;i<=Q[1].t;++i)
          a[CH[i].x]=CH[i].y;
        int LCA=lca(Q[1].l,Q[1].r);
        Work(Q[1].l,Q[1].r,LCA);
        Update(a[LCA],1);
        anss[Q[1].p]=Kth(Q[1].k);
        Update(a[LCA],-1);
        for(int i=2;i<=eq;++i)
          {
          	if(Q[i-1].t<Q[i].t) for(int j=Q[i-1].t+1;j<=Q[i].t;++j)
          	  {
                if(vis[CH[j].x])
                  {
                    Update(CH[j].y,1);
                    Update(a[CH[j].x],-1);
                  }
                a[CH[j].x]=CH[j].y;
              }
            else for(int j=Q[i-1].t;j>Q[i].t;--j)
              {
                if(vis[CH[j].x])
                  {
                    Update(CH[j].z,1);
                    Update(a[CH[j].x],-1);
                  }
                a[CH[j].x]=CH[j].z;
              }
            Work(Q[i-1].l,Q[i].l,lca(Q[i-1].l,Q[i].l));
            Work(Q[i-1].r,Q[i].r,lca(Q[i-1].r,Q[i].r));
            LCA=lca(Q[i].l,Q[i].r);
            Update(a[LCA],1);
            anss[Q[i].p]=Kth(Q[i].k);
            Update(a[LCA],-1);
          }
        for(int i=1;i<=eq;++i)
          if(anss[i]!=-1)
    	    printf("%d
    ",anss[i]);
    	  else
    	    puts("invalid request!");
    	return 0;
    }
  • 相关阅读:
    springboot集成websocket
    验证regex表达式本身是否有问题
    Quartz Cron表达式 生成
    Cannot run program "python": CreateProcess error=2, 系统找不到指定的文件
    遇到多个构造器参数时,要考虑用构造器
    考虑使用静态工厂代替构造器
    idea自定义注释
    layui2.4.0前的table隐藏列
    002、获取屏幕大小
    001、关于TextView的一些小知识
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4428522.html
Copyright © 2020-2023  润新知