BZOJ3052: [wc2013]糖果公园

依旧不会证明复杂度。。。。

此题需要注意下修改
讲t用于第三关键字排序

本傻逼第一发没有初始化块的大小
成功调戏一波评测姬(划

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long 
char c;
inline void read(int &a)
{
    a=0;do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
int Blo[100001];
struct Query
{
    int u,v,t,no;
    ll ans;
    inline void Bg(){if(Blo[u]>Blo[v])swap(u,v);}
    inline friend bool operator <(Query a,Query b)
    {return Blo[a.u]^Blo[b.u]?(Blo[a.u]<Blo[b.u]):(Blo[a.v]^Blo[b.v]?Blo[a.v]<Blo[b.v]:a.t<b.t);}
}L[100001],b[100001];
inline bool cmp(Query a,Query b)
{
    return a.no<b.no;
}
struct Chain
{
    int u;
    Chain *next;
    Chain(){next=NULL;}
}*Head[1000001];

inline void Add(int u,int v)
{
    Chain *tp=new Chain;
    tp->u=v;
    tp->next=Head[u];
    Head[u]=tp;
}
int tot,B,con;
int Cache[1000001];
int    dep[1000001], f[1000001][21];
void DFS(int u)
{
    for(Chain *tp=Head[u];tp;tp=tp->next)
      if(tp->u!=f[u][0])
         {
            f[tp->u][0]=u;
            dep[tp->u]=dep[u]+1;
            DFS(tp->u);
            if(tot>=B)
             {
                ++con;
                while(tot)Blo[Cache[tot--]]=con;
             }  
         }
    Cache[++tot]=u;
}
inline int LCA(int a,int b)
{
        int j;
    while(dep[a]^dep[b])
    {
        if(dep[a]<dep[b])swap(a,b);
        for(j=0;dep[f[a][j+1]]>dep[b];j++);
        a=f[a][j];
    }
    while(a^b)
    {
        for(j=0;f[a][j+1]^f[b][j+1];j++);
        a=f[a][j],b=f[b][j];
    }
    return a;
}


int n,m,q;
ll ret;
int v[1000001],w[1000001],co[1000001],s[100001],pre[100001];
bool vis[1000001];
inline void NodeXor(int x)
{
     if(vis[x]){ret-=(ll)w[s[co[x]]]*v[co[x]];s[co[x]]--;}
    else {s[co[x]]++;ret+=(ll)w[s[co[x]]]*v[co[x]];}
      vis[x]^=1;
}

inline void PathXor(int a,int b)
{
    while(a^b)
    {
        if(dep[a]<dep[b])swap(a,b);
        NodeXor(a);
        a=f[a][0];
    }
}

inline void C(int x,int y)
{
     if(!vis[x])co[x]=y;
     else 
      {
          NodeXor(x);
         co[x]=y;
          NodeXor(x);
      }

}


int main()
{

    int i,j,k;
    read(n),read(m),read(q);
    for(i=1;i<=m;i++)
      read(v[i]);
    for(i=1;i<=n;i++)
      read(w[i]);
    for(i=2;i<=n;i++)
       read(j),read(k),Add(j,k),Add(k,j);
    B=sqrt(n);
    for(i=1;i<=n;i++)
      read(co[i]),pre[i]=co[i];
    f[1][0]=1;
    DFS(1);   
    if(tot>=B)
          {
                ++con;
                while(tot)Blo[Cache[tot--]]=con;
             }  
    for(i=1;i<=20;i++)
      for(j=1;j<=n;j++)
        f[j][i]=f[f[j][i-1]][i-1];
    int lastu=1,lastv=1,op;
    int t=0,c1=0,c2=0;
    for(i=1;i<=q;i++)
      {
        read(op);
        if(op)
            read(L[++c1].u),read(L[c1].v),L[c1].no=c1,L[c1].t=c2,L[c1].Bg();    
        else read(b[++c2].u),read(b[c2].v),b[c2].no=pre[b[c2].u],pre[b[c2].u]=b[c2].v;
      }
    int f;
    sort(L+1,L+1+c1);
    for(i=1;i<=c1;i++)
      {   while(t<L[i].t)t++,C(b[t].u,b[t].v);
         while(t>L[i].t)C(b[t].u,b[t].no),t--;
         PathXor(lastu,L[i].u);PathXor(lastv,L[i].v);
         lastu=L[i].u;lastv=L[i].v;
         f=LCA(lastu,lastv);
        NodeXor(f);
         L[i].ans=ret;
        NodeXor(f);     
      }
    sort(L+1,L+1+c1,cmp);

    for(i=1;i<=c1;i++)
       printf("%lld\n",L[i].ans);
    return 0;
}

你可能感兴趣的:(BZOJ3052: [wc2013]糖果公园)