cf757g暂存

不知道哪里写挂了,一直过不去
但是正确性是有保证的。

#include<bits/stdc++.h>
using namespace std;
#define N 200010
#define ll long long
int h[N],v[N*2],w[N*2],nxt[N*2],ec,n,q,f[N],tp[N],p[N],sz[N],pp[N],id[N],ct,lc[N*100],rc[N*100],st[N],rt[N],cg,vv[N];
ll s[N*150],cc[N*150],sd[N],sp[N],d[N];
void add(int x,int y,int z){v[++ec]=y;w[ec]=z;nxt[ec]=h[x];h[x]=ec;}
void d1(int x,int fa){
	sz[x]=1;
	f[x]=fa;
	for(int i=h[x];i;i=nxt[i])
		if(v[i]!=fa){
			d[v[i]]=w[i]+d[x];
			vv[v[i]]=w[i];
			d1(v[i],x);
			sz[x]+=sz[v[i]];
			if(sz[p[x]]<sz[v[i]])
				p[x]=v[i];
		}
}
void d2(int x,int fa,int t){
	tp[x]=t;
	id[x]=++ct;
	st[ct]=x;
	if(p[x])
		d2(p[x],x,t);
	for(int i=h[x];i;i=nxt[i])
		if(v[i]!=fa&&v[i]!=p[x])
			d2(v[i],x,v[i]);
}
void add(int &o,int l,int r,int x,int y){
	if(r<x||y<l)return;
	++cg;
	lc[cg]=lc[o];
	rc[cg]=rc[o];
	cc[cg]=cc[o];
	s[cg]=s[o];
	o=cg;
	if(x<=l&&r<=y){
		cc[o]++;
		s[o]+=sp[r]-sp[l-1];
		return;
	}
	int md=(l+r)/2;
	add(lc[o],l,md,x,y);
	add(rc[o],md+1,r,x,y);
	s[o]=s[lc[o]]+s[rc[o]]+cc[o]*(sp[r]-sp[l-1]);
}
ll qq(int o,int l,int r,int x,int y,ll z){
	if(r<x||y<l)return 0;
	if(!o)return (sp[min(r,y)]-sp[max(l,x)-1])*z;
	if(x<=l&&r<=y)return z*(sp[r]-sp[l-1])+s[o];
	int md=(l+r)/2;
	return qq(lc[o],l,md,x,y,z+cc[o])+qq(rc[o],md+1,r,x,y,z+cc[o]);
}
void bd(int &o,int l,int r){
	o=++cg;
	if(l==r)return;
	int md=(l+r)/2;
	bd(lc[o],l,md);
	bd(rc[o],md+1,r);
}
void ad(int x,int y){
	while(y){
		add(rt[x],1,n,id[tp[y]],id[y]);
		y=f[tp[y]];
	}
}
ll qu(int x,int va){
	ll ans=0,y=va;
	while(y){
		ans+=qq(rt[x],1,n,id[tp[y]],id[y],0);
		y=f[tp[y]];
	}
	return x*d[va]+sd[x]-2*ans;
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1;i<=n;i++)
		scanf("%d",&pp[i]);
	for(int i=1;i<n;i++){
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);
		add(y,x,z);
	}
	d1(1,0);
	d2(1,0,1);
	for(int i=1;i<=n;i++){
		sd[i]=sd[i-1]+d[pp[i]];
		sp[i]=sp[i-1]+vv[st[i]];
	}
	bd(rt[0],1,n);
	for(int i=1;i<=n;i++){
		rt[i]=rt[i-1];
		ad(i,pp[i]);
	}
	ll la=0;
	for(int i=1;i<=q;i++){
		int op,l,r,x;
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&l,&r,&x);
			la%=(1<<30);
			x^=la;
			l^=la;
			r^=la;
			la=qu(r,x)-qu(l-1,x);
			printf("%lld\n",la);
		}
		else{
			scanf("%d",&x);
			la%=(1<<30);
			x^=la;
			swap(pp[x],pp[x+1]);
			sd[x]=sd[x-1]+d[pp[x]];
			rt[x]=rt[x-1];
			if(cg<=29000000)ad(x,pp[x]);
			else{
				for(int j=1;j<=cg;j++)
					lc[j]=rc[j]=s[j]=cc[j]=0;
				cg=0;
				for(int j=1;j<=n;j++){
					rt[j]=rt[j-1];
					ad(j,pp[j]);
				}
			}
		}
	}
}
posted @   celerity1  阅读(125)  评论(0编辑  收藏  举报
(评论功能已被禁用)
点击右上角即可分享
微信分享提示