【树上莫队】【带修莫队】bzoj3052 [wc2013]糖果公园

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 100001
typedef long long ll;
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;
}
int n,m,a[N],b[N];
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,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];
}
ll anss[N],ans;
int Vs[N],Ws[N],q;
bool vis[N];
int T[N];
void Update(int x,int op)
{
	if(op==-1) ans-=(ll)Vs[x]*(ll)Ws[T[x]];
	T[x]+=op;
	if(op==1) ans+=(ll)Vs[x]*(ll)Ws[T[x]];
}
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 main()
{
	int x,y; bool op;
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=m;++i) scanf("%d",&Vs[i]);
	for(int i=1;i<=n;++i) scanf("%d",&Ws[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) scanf("%d",&a[i]);
	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;
	memcpy(b,a,sizeof(int)*(n+1));
	for(int i=1;i<=q;++i)
	  {
	  	scanf("%d",&op);
	  	if(!op)
	  	  {
	  	  	++ec; ++en;
	  	  	scanf("%d%d",&CH[ec].x,&CH[ec].y);
	  	  	CH[ec].z=b[CH[ec].x];
	  	  	b[CH[ec].x]=CH[ec].y;
	  	  }
	  	else
	  	  {
	  	  	++eq;
	  	  	scanf("%d%d",&Q[eq].l,&Q[eq].r);
	  	  	Q[eq].t=ec; Q[eq].p=eq;
	  	  }
	  }
    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]=ans;
    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]=ans;
        Update(a[LCA],-1);
      }
    for(int i=1;i<=eq;++i)
	  printf("%lld\n",anss[i]);
	return 0;
}
posted @ 2015-04-15 15:34  AutSky_JadeK  阅读(140)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト