不知道哪里写挂了,一直过不去
但是正确性是有保证的。
#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
",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]);
}
}
}
}
}