• 糖果公园


    这是树上待修莫队的裸题。

    可是我已开始应为吧cmp写错了TLE成30,呜呜……

    看代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int maxn=1e5+10;
    int n,m,q,a[maxn<<1],fir[maxn],las[maxn],top;
    int v[maxn],w[maxn];
    int beg[maxn],nex[maxn<<1],to[maxn<<1],e;
    inline void add(int x,int y){
        e++;nex[e]=beg[x];
        beg[x]=e;to[e]=y;
    }
    inline int read(){
        int x=0,f=1;
        char c=getchar();
        while(c<'0'||c>'9'){
            if(c=='-')f=-1;
            c=getchar();
        }
        while(c>='0'&&c<='9'){
            x=(x<<1)+(x<<3)+c-'0';
            c=getchar();
        }
        return x*f;
    }
    int dep[maxn],f[maxn][20],c[maxn];
    inline void dfs(int x,int fa){
        a[++top]=x;
        fir[x]=top;
        dep[x]=dep[fa]+1;
        f[x][0]=fa;
        for(int i=1;i<=19;i++)
            f[x][i]=f[f[x][i-1]][i-1];
        for(int i=beg[x];i;i=nex[i])
            if(to[i]!=fa)dfs(to[i],x);
        a[++top]=x;
        las[x]=top;
    }
    inline int lca(int x,int y){
        if(dep[x]<dep[y])swap(x,y);
        for(int i=19;i>=0;i--)
            if(dep[x]-(1<<i)>=dep[y])
                x=f[x][i];
        if(x==y)return x;
        for(int i=19;i>=0;i--)
            if(f[x][i]!=f[y][i]){
                x=f[x][i];
                y=f[y][i];
            }
        return f[x][0];
    }
    struct change{
        int pos,col;
    }ch[maxn];
    struct query{
        int l,r,bl,br,lca,id,cha;
    }que[maxn];
    inline int cmp(query x,query y){
        return (x.bl^y.bl)?(x.bl<y.bl):((x.br^y.br)?(x.br<y.br):((x.br&1)?(x.cha<y.cha):(x.cha>y.cha)));
    }
    int vis[maxn],now,cnt[maxn];
    inline void dele(int x){
        if(!vis[x])now+=v[c[x]]*w[++cnt[c[x]]];
        else now-=v[c[x]]*w[cnt[c[x]]--];
        vis[x]^=1;
    }
    int ans[maxn];
    signed main(){
        n=read(),m=read(),q=read();
        int len=pow(n,2.0/3.0);
        for(int i=1;i<=m;i++)
            v[i]=read();
        for(int i=1;i<=n;i++)
            w[i]=read();
        int opt,x,y;
        for(int i=1;i<n;i++){
            x=read(),y=read();
            add(x,y),add(y,x);
        }
        dfs(1,0);
        for(int i=1;i<=n;i++)
            c[i]=read();
        int t1=0,t2=0;
        for(int i=1;i<=q;i++){
            opt=read(),x=read(),y=read();
            if(opt==0){
                t1++;
                ch[t1].pos=x;
                ch[t1].col=y;
            }else{
                t2++;
                que[t2].id=t2;
                que[t2].cha=t1;
                if(dep[x]>dep[y])swap(x,y);
                if(lca(x,y)==x){
                    que[t2].l=fir[x];
                    que[t2].r=fir[y];
                }else{
                    que[t2].l=las[x];
                    que[t2].r=fir[y];
                    que[t2].lca=lca(x,y);
                }
                que[t2].bl=que[t2].l/len;
                que[t2].br=que[t2].r/len;
            }
        }
        sort(que+1,que+1+t2,cmp);
        int l=1,r=0,ti=0;
        for(int i=1;i<=t2;i++){
            while(l<que[i].l)dele(a[l++]);
            while(l>que[i].l)dele(a[--l]);
            while(r<que[i].r)dele(a[++r]);
            while(r>que[i].r)dele(a[r--]);
            while(ti<que[i].cha){
                ti++;
                if(vis[ch[ti].pos]){
                    now-=v[c[ch[ti].pos]]*w[cnt[c[ch[ti].pos]]--];
                    now+=v[ch[ti].col]*w[++cnt[ch[ti].col]];    
                }swap(ch[ti].col,c[ch[ti].pos]);
            }
            while(ti>que[i].cha){
                if(vis[ch[ti].pos]){
                    now-=v[c[ch[ti].pos]]*w[cnt[c[ch[ti].pos]]--];
                    now+=v[ch[ti].col]*w[++cnt[ch[ti].col]];    
                }swap(ch[ti].col,c[ch[ti].pos]);
                ti--;
            }
            if(que[i].lca)dele(que[i].lca);
            ans[que[i].id]=now;
            if(que[i].lca)dele(que[i].lca);
        }
        for(int i=1;i<=t2;i++)
            printf("%lld
    ",ans[i]);
        return 0;
    } 

    总体来说还是挺好写的,毕竟我都是两遍就过了……

    深深地感到自己的弱小。

  • 相关阅读:
    全面理解javascript的caller,callee,call,apply概念(修改版)
    动态显示更多信息(toggle_visible函数的运用)
    再论call和apply
    RSS News Module的应用
    准备制作一套全新的DNN皮肤(包括个人定制或企业级定制)
    ControlPanel研究系列二:简单Ajax模式的ControlPanel(SimplAjax)
    New_Skin发布了....
    如何定制dnn的FckEditor
    Blog已迁移到dnnsun.com(最新DotNetNuke咨询平台)
    新DNN皮肤的经验及成果分享
  • 原文地址:https://www.cnblogs.com/syzf2222/p/12503559.html
Copyright © 2020-2023  润新知