UOJ 58 [WC2013]糖果公园

来源:互联网 发布:js包装函数是什么 编辑:程序博客网 时间:2024/04/30 19:44

树上莫队

题解详见VFK大爷的 :
http://vfleaking.blog.163.com/blog/static/174807634201311011201627/

orz vfleaking orz vfleaking orz vfleaking orz vfleaking

这题在本机对拍的时候,忘记在分块里面初始化1,导致所有节点都没有进行分块操作。结果自己拍大数据跑的贼快,大点都只要一秒不到???(可能是因为数据随机?原因成谜。。。)然后非常喜悦 地交上去就T光光了。

真是一段有趣的经历- -

#include<cstdio>#include<cstring>#include<algorithm>#define ll long long#define reg register#define N 100005#define SIZE 2154#define getc() (S == T && (T = (S = B) + fread(B, 1, 1<<23, stdin), S == T) ? 0 : *S++)using namespace std;char B[1<<23], *S = B, *T = B;bool vis[N];ll ans, print[N], v[N];int bin[20], col[N], w[N], last[N], que[N], belong[N], siz[N], block, fa[N][20], dep[N], tot[N];struct edge{int next,to;}e[N<<1];int ecnt;struct query{int x, y, t, id;}q[N];int qcnt;struct change{int x, from, to;}c[N];int ccnt;int in(){    reg int r = 0;    reg char c = getc();    while(c<'0'||c>'9')c=getc();    while(c>='0'&&c<='9')r=r*10+c-'0',c=getc();    return r;}bool cmp(query a, query b){    if(belong[a.x]==belong[b.x] && belong[a.y]==belong[b.y])return a.t<b.t;    else if(belong[a.x]==belong[b.x])return belong[a.y]<belong[b.y];    else return belong[a.x]<belong[b.x];}void addedge(int a, int b){    e[++ecnt]=(edge){last[a],b};    last[a]=ecnt;} void addnode(int x, int f){    if(siz[belong[f]]<SIZE)        belong[x]=belong[f];    else        belong[x]=++block;    siz[belong[x]]++;}void makeblock(){    que[0]=belong[1]=siz[1]=block=1;    for(int head=0, tail=1; head<tail; head++)    {        int x=que[head];        for(int i = last[x]; i; i=e[i].next)        {            int y=e[i].to;            if(belong[y])continue;            que[tail++]=y;            addnode(y,x);        }    }}void dfs(int x){    dep[x]=dep[fa[x][0]]+1;    for(int i = 1; bin[i]<=dep[x]; i++)        fa[x][i]=fa[fa[x][i-1]][i-1];    for(int i = last[x]; i; i=e[i].next)    {        int y=e[i].to;        if(y==fa[x][0])continue;        fa[y][0]=x;        dfs(y);    }}void reverse(int x){    if(vis[x])ans-=w[tot[col[x]]]*v[col[x]], tot[col[x]]--;    else tot[col[x]]++, ans+=w[tot[col[x]]]*v[col[x]];    vis[x]=!vis[x];}void make(int x, int y){    while(x!=y)    {        if(dep[x]>dep[y])reverse(x), x=fa[x][0];        else reverse(y), y=fa[y][0];    }}void turn(int x, int y){    if(vis[x])    {        ans-=w[tot[col[x]]]*v[col[x]];        tot[col[x]]--;        tot[y]++;        ans+=w[tot[y]]*v[y];     }    col[x]=y;}int lca(int x, int y){    if(dep[x]<dep[y])swap(x,y);    int t = dep[x]-dep[y];    for(int i = 0; bin[i]<=t; i++)        if(t&bin[i])            x=fa[x][i];    for(int i = 19; i>=0; i--)    {        if(fa[x][i]!=fa[y][i])            x=fa[x][i], y=fa[y][i];    }    return x==y?x:fa[x][0];}int main(){    int n=in(), m=in(), Q=in();    bin[0]=1;    for(int i = 1; i < 20; i++)        bin[i]=bin[i-1]<<1;    for(int i = 1; i <= m; i++)        v[i]=in();    for(int i = 1; i <= n; i++)        w[i]=in();    for(int i = 1, a, b; i < n; i++)    {        a=in(); b=in();        addedge(a,b);        addedge(b,a);    }    for(int i = 1; i <= n; i++)        col[i]=in();    makeblock();    dfs(1);    for(int i = 1; i <= Q; i++)    {        int op=in(), x=in(), y=in();        if(op==0)        {            c[++ccnt]=(change){x,col[x],y};            col[x]=y;        }        else        {            if(x>y)swap(x,y);            q[++qcnt]=(query){x,y,ccnt,qcnt};        }    }    sort(q+1,q+1+qcnt,cmp);    make(q[1].x,q[1].y);    for(;ccnt<q[1].t;ccnt++)        turn(c[ccnt+1].x, c[ccnt+1].to);    for(;ccnt>q[1].t;ccnt--)        turn(c[ccnt].x, c[ccnt].from);    int t=lca(q[1].x,q[1].y);    reverse(t);     print[q[1].id]=ans;    reverse(t);    for(int i = 2; i <= qcnt; i++)    {        for(;ccnt<q[i].t;ccnt++)            turn(c[ccnt+1].x, c[ccnt+1].to);        for(;ccnt>q[i].t;ccnt--)            turn(c[ccnt].x, c[ccnt].from);        make(q[i].x,q[i-1].x);        make(q[i].y,q[i-1].y);        int temp=lca(q[i].x,q[i].y);        reverse(temp);        print[q[i].id]=ans;        reverse(temp);    }    for(int i = 1; i <= qcnt; i++)        printf("%lld\n",print[i]);} 
1 0
原创粉丝点击