分块2(莫队)

19e7c0d7d8ed43468cc9bfc0862cc0f4
//P2709
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,k,size,ans[100010],a[1000010],cnt[1000010],l=1,r,sm;
struct Q{
    int l,r,id;
}q[1000010];
bool operator<(Q a,Q b){
    if(a.l/size==b.l/size){
        return a.r<b.r;
    }
    return a.l/size<b.l/size;
}
void Del(int p){
    sm-=(cnt[a[p]]*cnt[a[p]]);
    cnt[a[p]]--;
    sm+=(cnt[a[p]]*cnt[a[p]]);
}
void Add(int p){
    sm-=(cnt[a[p]]*cnt[a[p]]);
    cnt[a[p]]++;
    sm+=(cnt[a[p]]*cnt[a[p]]);
}
signed main(){
    ios::sync_with_stdio(0);
    cin>>n>>m>>k;
    size=sqrt(n);
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=m;i++){
        cin>>q[i].l>>q[i].r;
        q[i].id=i;
    }
    sort(q+1,q+m+1);
    for(int i=1;i<=m;i++){
        while(l<q[i].l){
            Del(l++);
        }
        while(l>q[i].l){
            Add(--l);
        }
        while(r<q[i].r){
            Add(++r);
        }
        while(r>q[i].r){
            Del(r--);
        }
        ans[q[i].id]=sm;
    }
    for(int i=1;i<=m;i++){
        cout<<ans[i]<<endl;
    }
}
//P1903
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[1000010],cnt_Q,cnt_R,cnt[1000010];
int l=1,r,t,sm,size,ans[1000010];
struct Q{
    int l,r,time,id;
}q[1000010];
struct C{
    int col,pos;
}c[100010];
bool operator<(Q a,Q b){
    if(a.l/size==b.l/size){
        if(a.r/size==b.r/size){
            return a.time<b.time;
        }
        return a.r<b.r;
    }
    return a.l/size<b.l/size;
}
void Add(int p){
    cnt[a[p]]++;
    if(cnt[a[p]]==1){
        sm++;
    }
}
void Del(int p){
    cnt[a[p]]--;
    if(cnt[a[p]]==0){
        sm--;
    }
}
signed main(){
    cin>>n>>m;
    size=pow(n,0.666);
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=m;i++){
        char a;
        int x,y;
        cin>>a>>x>>y;
        if(a=='Q'){
            cnt_Q++;
            q[cnt_Q].l=x;
            q[cnt_Q].r=y;
            q[cnt_Q].id=cnt_Q;
            q[cnt_Q].time=cnt_R;
        }
        if(a=='R'){
            cnt_R++;
            c[cnt_R].pos=x;
            c[cnt_R].col=y;
        }
    }
    sort(q+1,q+cnt_Q+1);
    for(int i=1;i<=cnt_Q;i++){
        while(l<q[i].l){
            Del(l++);
        }
        while(l>q[i].l){
            Add(--l);
        }
        while(r<q[i].r){
            Add(++r);
        }
        while(r>q[i].r){
            Del(r--);
        }
        while(t<q[i].time){
            t++;
            if(c[t].pos>=q[i].l&&c[t].pos<=q[i].r){
                cnt[a[c[t].pos]]--;
                cnt[c[t].col]++;
                if(cnt[a[c[t].pos]]==0){
                    sm--;
                }
                if(cnt[c[t].col]==1){
                    sm++;
                }    
            }
            swap(a[c[t].pos],c[t].col);
        }
        while(t>q[i].time){
            if(c[t].pos>=q[i].l&&c[t].pos<=q[i].r){
                cnt[a[c[t].pos]]--;
                cnt[c[t].col]++;
                if(cnt[a[c[t].pos]]==0){
                    sm--;
                }
                if(cnt[c[t].col]==1){
                    sm++;
                }
            }
            swap(a[c[t].pos],c[t].col);
            t--;
        }
        ans[q[i].id]=sm;
    }
    for(int i=1;i<=cnt_Q;i++){
        cout<<ans[i]<<endl;
    }
}
//P4074
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,q,uu,vv,c[500010],opt,l,r,tt,tot,ver[500010],hed[500010],nxt[500010];
int v[500010],w[500010],ans[500010],sum,fa[500010][21],vis[500010];
int in[500010],out[500010],kk,back[500010],dep[500010],f[500010];
int bl,t[500010],flag[500010],qq,rr;
struct ques{
    int u,v,lca,l,r,id,t;
}qu[1000010];
struct point{
    int pos,candy;
}re[1000010];
bool cmp(ques a,ques b){
    if(a.l/bl==b.l/bl){
        if(a.r/bl==b.r/bl){
            return a.t<b.t;
        }
        return a.r<b.r;
    }
    return a.l/bl<b.l/bl;
}
void add(int a,int b){
    ver[++tot]=b,nxt[tot]=hed[a],hed[a]=tot;
}
void dfs(int u,int ff){
    f[u]=ff;
    in[u]=++kk;
    back[kk]=u;
    for(int i=hed[u];i;i=nxt[i]){
        int v=ver[i];
        if(v==ff){
            continue;
        }
        dfs(v,u);
    }
    out[u]=++kk;
    back[kk]=u;
}
void dfslca(int u){
    vis[u]=1;
    for(int i=1;(1<<i)<=dep[u];i++){
        fa[u][i]=fa[fa[u][i-1]][i-1];
    }
    for(int i=hed[u];i;i=nxt[i]){    
        int v=ver[i];
        if(vis[v]){
            continue;
        }
        dep[v]=dep[u]+1;
        dfslca(v);
    }
}
int LCA(int x,int y){
    if(dep[x]<dep[y]){
        swap(x,y);
    }
    int h=dep[x]-dep[y];
    for(int i=0;(1<<i)<=h;i++){
        if((1<<i)&h){
            x=fa[x][i];
        }
    }
    if(x==y){
        return x;
    }
    for(int i=20;i>=0;i--){
        if(fa[x][i]!=fa[y][i]){
            x=fa[x][i];
            y=fa[y][i];
        }
    }
    return fa[x][0];
}
void change(int x){
    if(flag[re[x].pos]==1){
        t[c[re[x].pos]]--;
        sum-=w[t[c[re[x].pos]]+1]*v[c[re[x].pos]];
        t[re[x].candy]++;
        sum+=w[t[re[x].candy]]*v[re[x].candy];
    }
    swap(re[x].candy,c[re[x].pos]);
}
signed main(){
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=m;i++){
        scanf("%lld",&v[i]);
    }
    for(int i=1;i<=n;i++){
        scanf("%lld",&w[i]);
    }
    for(int i=1;i<=n-1;i++){
        scanf("%d%d",&uu,&vv);
        add(uu,vv);
        add(vv,uu);
    }
    for(int i=1;i<=n;i++){
        scanf("%d",&c[i]);
    }
    dfs(1,1);
    for(int i=1;i<=n;i++){
        fa[i][0]=f[i];
    }
    dfslca(1);
    bl=sqrt(2*n);
    for(int i=1;i<=q;i++){
        scanf("%d",&opt);
        scanf("%d%d",&uu,&vv);
        if(opt==0){
            re[++rr].pos=uu;
            re[rr].candy=vv;
        }
        if(opt==1){
            qu[++qq].lca=LCA(uu,vv);
            qu[qq].id=qq;
            qu[qq].t=rr;
            qu[qq].u=uu;qu[qq].v=vv;
            if(in[qu[qq].u]>in[qu[qq].v]){
                swap(qu[qq].u,qu[qq].v);
            }
            if(qu[qq].lca==qu[qq].u){
                qu[qq].l=in[qu[qq].u];
                qu[qq].r=in[qu[qq].v];
                qu[qq].lca=0;
            }
            else{
                qu[qq].l=out[qu[qq].u];
                qu[qq].r=in[qu[qq].v];
            }
        }
    }
    sort(qu+1,qu+qq+1,cmp);
    for(int i=1;i<=qq;i++){
        while(l<qu[i].l){
            flag[back[l]]--;
            if(flag[back[l]]==1){
                t[c[back[l]]]++;
            }
            if(flag[back[l]]==0){
                t[c[back[l]]]--;
            }
            if(flag[back[l]]==0){
                sum-=w[t[c[back[l]]]+1]*v[c[back[l]]];
            }
            if(flag[back[l]]==1){
                sum+=w[t[c[back[l]]]]*v[c[back[l]]];
            }
            l++;
        }
        while(l>qu[i].l){
            flag[back[--l]]++;
            if(flag[back[l]]==1){
                t[c[back[l]]]++;
            }
            if(flag[back[l]]==2){
                t[c[back[l]]]--;
            }
            if(flag[back[l]]==2){
                sum-=w[t[c[back[l]]]+1]*v[c[back[l]]];
            }
            if(flag[back[l]]==1){
                sum+=w[t[c[back[l]]]]*v[c[back[l]]];
            }
        }
        while(r<qu[i].r){
            flag[back[++r]]++;
            if(flag[back[r]]==1){
                t[c[back[r]]]++;
            }
            if(flag[back[r]]==2){
                t[c[back[r]]]--;
            }
            if(flag[back[r]]==2){
                sum-=w[t[c[back[r]]]+1]*v[c[back[r]]];
            }
            if(flag[back[r]]==1){
                sum+=w[t[c[back[r]]]]*v[c[back[r]]];
            }
        }
        while(r>qu[i].r){
            flag[back[r]]--;
            if(flag[back[r]]==1){
                t[c[back[r]]]++;
            }
            if(flag[back[r]]==0){
                t[c[back[r]]]--;
            }
            if(flag[back[r]]==0){
                sum-=w[t[c[back[r]]]+1]*v[c[back[r]]];
            }
            if(flag[back[r]]==1){
                sum+=w[t[c[back[r]]]]*v[c[back[r]]];
            }
            r--;
        }
        while(tt<qu[i].t){
            change(++tt);
        }
        while(tt>qu[i].t){
            change(tt--);
        }
        if(qu[i].lca){
            t[c[qu[i].lca]]++;
            sum+=w[t[c[qu[i].lca]]]*v[c[qu[i].lca]];
        }
        ans[qu[i].id]=sum;
        if(qu[i].lca){
            t[c[qu[i].lca]]--;
            sum-=w[t[c[qu[i].lca]]+1]*v[c[qu[i].lca]];
        }
    }
    for(int i=1;i<=qq;i++){
        printf("%lld\n",ans[i]);
    }
    return 0;
}

 

posted @ 2026-06-14 22:11  heccqwq  阅读(4)  评论(0)    收藏  举报