带修树上莫队求调
查看原帖
带修树上莫队求调
535996
Blanc_min楼主2025/7/30 21:32

只过了前三个点,后面的全T飞了,第四个点跑了27S,所以应该不是常数的问题... 调很久了...

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define _ 200005
ll n,m,q,v[_],w[_],a[_],tt,now,num[_],B,fa[_][21],ol[_],siz,fir[_],sec[_],dep[_],l,r,t,ans,b[_],bj[_],bk[_];
struct bb {
	ll l,r,i,ans,t;
	bool operator < (const bb &k) const {
		if(num[l]!=num[k.l]) return num[l]<num[k.l];
		if(t!=k.t) return t<k.t;
		return r<k.r;
	}
}que[_];
struct node { ll x,y,f; } chk[_];
struct Edge {ll to, next;} edge[_<<1];
ll head[_],ecnt;
inline void addEdge(int u, int v) {
    edge[++ecnt] = {v, head[u]};
    head[u] = ecnt;
}
bool cmp(bb a,bb b) {return a.i<b.i;}
inline unsigned read() {
    unsigned x = 0;
    char c = getchar();
    while (!isdigit(c)) c = getchar();
    do {
        x = (x << 1) + (x << 3) + (c ^ 48);
    } while (isdigit(c = getchar()));
    return x;
}
inline void dfs(ll x,ll f) {
	fa[x][0]=f,dep[x]=dep[f]+1;
	for(int i=1;i<21;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
	ol[++siz]=x,fir[x]=siz;
	for (ll i=head[x];i;i=edge[i].next) {
        ll y=edge[i].to;
        if (y==f) continue;
        dfs(y,x);
    }
	ol[++siz]=x,sec[x]=siz;
}
inline ll lca(ll x,ll y) {
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=20;i>=0;i--) if(dep[fa[x][i]]>=dep[y]) 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];
}
inline void chkt(ll T) {
	while(t<T) {
		t++;
		if(bk[chk[t].x]==1) {
			ans-=v[chk[t].f]*w[bj[chk[t].f]];
			bj[chk[t].f]--;
			bj[chk[t].y]++;
			ans+=v[chk[t].y]*w[bj[chk[t].y]];
		}
		a[chk[t].x]=chk[t].y;
	}
	while(t>T) {
		if(bk[chk[t].x]==1) {
			ans-=v[chk[t].y]*w[bj[chk[t].y]];
			bj[chk[t].y]--;
			bj[chk[t].f]++;
			ans+=v[chk[t].f]*w[bj[chk[t].f]];
		}
		a[chk[t].x]=chk[t].f;
		t--;
	}
}
inline void mov(ll L,ll R) {
	while(l<L) {
		bk[ol[l]]--;
		if(bk[ol[l]]==0) {
			ans-=v[a[ol[l]]]*w[bj[a[ol[l]]]];
			bj[a[ol[l]]]--;
		}
		if(bk[ol[l]]==1) {
			bj[a[ol[l]]]++;
			ans+=v[a[ol[l]]]*w[bj[a[ol[l]]]];
		}
		l++;
		if(l>r) {
			r++;
			bk[ol[r]]++;
			if(bk[ol[r]]==2) {
				ans-=v[a[ol[r]]]*w[bj[a[ol[r]]]];
				bj[a[ol[r]]]--;
			}
			if(bk[ol[r]]==1) {
				bj[a[ol[r]]]++;
				ans+=v[a[ol[r]]]*w[bj[a[ol[r]]]];
			}
		}
	}
	while(l>L) {
		l--;
		bk[ol[l]]++;
		if(bk[ol[l]]==2) {
			ans-=v[a[ol[l]]]*w[bj[a[ol[l]]]];
			bj[a[ol[l]]]--;
		}
		if(bk[ol[l]]==1) {
			bj[a[ol[l]]]++;
			ans+=v[a[ol[l]]]*w[bj[a[ol[l]]]];
		}
	}
	while(r<R) {
		r++;
		bk[ol[r]]++;
		if(bk[ol[r]]==2) {
			ans-=v[a[ol[r]]]*w[bj[a[ol[r]]]];
			bj[a[ol[r]]]--;
		}
		if(bk[ol[r]]==1) {
			bj[a[ol[r]]]++;
			ans+=v[a[ol[r]]]*w[bj[a[ol[r]]]];
		}
	}
	while(r>R) {
		bk[ol[r]]--;
		if(bk[ol[r]]==0) {
			ans-=v[a[ol[r]]]*w[bj[a[ol[r]]]];
			bj[a[ol[r]]]--;
		}
		if(bk[ol[r]]==1) {
			bj[a[ol[r]]]++;
			ans+=v[a[ol[r]]]*w[bj[a[ol[r]]]];
		}
		r--;
	}
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	freopen("P4074_4.in","r",stdin);
	freopen("ans.out","w",stdout);
	double TT=clock();
	n=read(),m=read(),q=read();B=pow(n*2,2.0/3);
	for(int i=1;i<=m;i++) v[i]=read();
	for(int i=1;i<=n;i++) w[i]=read();
	for(int i=1,x,y;i<n;i++) {
		x=read(),y=read();
        addEdge(x,y);
        addEdge(y,x);
	}
	for(int i=1;i<=n;i++) a[i]=read(),b[i]=a[i];
	for(int i=1;i<=q;i++) {
		ll op=read(),x=read(),y=read();
		if(!op) {
			chk[++now].x=x,chk[now].y=y,chk[now].f=b[x];
			b[x]=y;
		}
		else {
			que[++tt].l=x,que[tt].r=y;
			que[tt].t=now,que[tt].i=i;             
		}
	}
	dfs(1,1);
	for(int i=1;i<=siz;i++) num[i]=(ll)(i/B)+1;
	sort(que+1,que+tt+1);
//	for(ll i=1;i<=tt;i++) cerr<<que[i].l<<' '<<num[que[i].l]<<" "<<num[que[i].r]<<' '<<que[i].t<<endl;
	for(int i=1;i<=tt;i++) {
//		cerr<<clock()-TT<<' '<<i<<' '<<tt<<endl;
		chkt(que[i].t);
//		cerr<<clock()-TT<<endl;
		ll c=lca(que[i].l,que[i].r);
		if(c==que[i].l||c==que[i].r) {
			if(l==r&&l==0) l=min(fir[que[i].l],fir[que[i].r]),r=l-1;
			mov(min(fir[que[i].l],fir[que[i].r]),max(fir[que[i].l],fir[que[i].r]));
			que[i].ans=ans;
		}
		else {
			if(l==r&&l==0) l=min(sec[que[i].l],sec[que[i].r]),r=l-1;
			mov(min(sec[que[i].l],sec[que[i].r]),max(fir[que[i].l],fir[que[i].r]));
			que[i].ans=ans+v[a[c]]*w[bj[a[c]]+1];
		}
//		cerr<<clock()-TT<<endl;
	}
	sort(que+1,que+tt+1,cmp);
	for(int i=1;i<=tt;i++) cout<<que[i].ans<<endl;
//	cerr<<clock()-TT<<endl;
	return 0;
} 
2025/7/30 21:32
加载中...