P4074糖果公园 带修莫队WA+TLE 0分求调
  • 板块灌水区
  • 楼主__Legends__
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/4/5 16:56
  • 上次更新2024/4/5 19:38:21
查看原帖
P4074糖果公园 带修莫队WA+TLE 0分求调
927858
__Legends__楼主2024/4/5 16:56

过样例

下载测试点1测试发现和答案一样

但是提交时没对

大佬求调

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
int n,m,q,op,x,y,c[N],dfn[2*N],st[N],en[N],tot,fa[N][25],b[N],q1,tim,vis[N];
bool used[N];
ll v[N],w[N],ans[N],temp,cnt[N];
vector<int> g[N];
struct Query{
    int l,r,t,id,lca;
    Query(){}
    Query(int _l,int _r,int _t,int _id,int _lca):l(_l),r(_r),t(_t),id(_id),lca(_lca){}
    bool operator < (const Query &p)const{
        return b[l]==b[p.l]?(b[r]==b[p.r]?t<p.t:b[r]<b[p.r]):b[l]<b[p.l];
    }  
}p[N];
struct Modi{
	int p,f;
	Modi(){}
	Modi(int _p,int _f):p(_p),f(_f){}
}modi[N];
void dfs(int x,int father){
	st[x]=++tot;
    dfn[tot]=x;
    fa[x][0]=father;
    for(int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
    for(int i=0;i<g[x].size();i++){
        int son=g[x][i];
        if(son==father) continue;
        dfs(son,x);
    }
    en[x]=++tot;
    dfn[tot]=x;
}
int LCA(int x,int y){
	if(x==y) return x;
	if(st[x]>st[y]) swap(x,y);
	for(int i=20;i>=0;i--)
		if(st[fa[y][i]]>st[x]){
			y=fa[y][i];
		}
	return fa[y][0];
}
void add(int x){
    vis[x]++;
    if(vis[x]==1){
    	cnt[c[x]]++;
    	used[x]=true;
    	temp+=w[cnt[c[x]]]*v[c[x]];
    }
    if(vis[x]==2){
		temp-=w[cnt[c[x]]]*v[c[x]];
    	cnt[c[x]]--;
    	used[x]=false;
    }
}
void del(int x){
   	vis[x]--;
    if(vis[x]==1){
    	cnt[c[x]]++;
    	used[x]=true;
    	temp+=w[cnt[c[x]]]*v[c[x]];
    }
    if(!vis[x]){
		temp-=w[cnt[c[x]]]*v[c[x]];
    	cnt[c[x]]--;
    	used[x]=false;
    }
}
void modify(int t){
	int x=modi[t].p,y=modi[t].f;
	if(used[x]){
		temp-=w[cnt[c[x]]]*v[c[x]];
    	cnt[c[x]]--;
		cnt[y]++;
    	temp+=w[cnt[y]]*v[y];
	}
	swap(c[x],modi[t].f);
}
int main(){
    scanf("%d%d%d",&n,&m,&q);
    ll bs=cbrt(1ll*n*n);
	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;i++){
		scanf("%d%d",&x,&y);
		g[x].push_back(y);
		g[y].push_back(x);
	}
	for(int i=1;i<=n;i++) scanf("%d",&c[i]);
	for(int i=1;i<=2*n;i++) b[i]=(i-1)/bs+1;
	dfs(1,0);
	while(q--){
		scanf("%d%d%d",&op,&x,&y);
		if(op==1){
			if(st[x]>st[y]) swap(x,y);
			int lca=LCA(x,y);
			if(lca==x) p[++q1]=Query(st[x],st[y],tim,q1,0);
			else p[++q1]=Query(en[x],st[y],tim,q1,lca);
		} 
		else modi[++tim]=Modi(x,y);
	}
	sort(p+1,p+q1+1);
	int l=1,r=0,t=0;
	for(int i=1;i<=q1;i++){
		while(r<p[i].r) add(dfn[++r]);
		while(r>p[i].r) del(dfn[r--]);
        while(l<p[i].l) del(dfn[l++]);
		while(l>p[i].l) add(dfn[--l]);
        while(t<p[i].t) modify(++t);
        while(t>p[i].t) modify(t--);
		if(p[i].lca) add(p[i].lca);
        ans[p[i].id]=temp;
        if(p[i].lca) del(p[i].lca);
	}
	for(int i=1;i<=q1;i++) printf("%lld\n",ans[i]);
    return 0;
}
2024/4/5 16:56
加载中...