实在是卡不下去了,帮看看是不是哪里写挂了。。。
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define pb(x) push_back(x)
typedef long long ll;
typedef long double ld;
using namespace std;
const int N=400010,M=800010;
inline int max(int x,int y){return x>y?x:y;}
inline int min(int x,int y){return x<y?x:y;}
inline void swap(int &x,int &y){x^=y^=x^=y;}
int hc[N],vc[M],ec[M],Nc[M],tc=1;
int head[N],ver[M],edge[M],Next[M],tot=1;
int n,m,t,top,cnt,mid,maxpt,p[N],rt[N],sz[N],vis[M];
int in[N],st[M][19],lg[M],ts;
ll lastans,d[N],B=(1<<30)-1;
vector<int> s;
vector<bool> v[N];
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||'9'<c){if(x=='-')f=-1;c=getchar();}
while('0'<=c&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
void ac(int x,int y,int z){
vc[++tc]=y,ec[tc]=z,Nc[tc]=hc[x],hc[x]=tc;
}
void add(int x,int y,int z){
ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;
}
struct Tree{
int l,r,e;
int lc,rc;
ll ld,rd;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define e(x) tree[x].e
#define lc(x) tree[x].lc
#define rc(x) tree[x].rc
#define ld(x) tree[x].ld
#define rd(x) tree[x].rd
}tree[N<<5];
void build(int x,int fa){
for(int i=hc[x];i;i=Nc[i])
if(vc[i]!=fa)s.pb(i);
int lst=x;
while(s.size()){
int i=s.back();s.pop_back();
int y=vc[i],z=ec[i];
add(lst,y,z),add(y,lst,z);
if(s.size()==1){
i=s.back();s.pop_back();
y=vc[i],z=ec[i];
add(lst,y,z),add(y,lst,z);
}
else if(s.size()>1){
++cnt;
add(lst,cnt,0),add(cnt,lst,0);
lst=cnt;
}
}
for(int i=hc[x];i;i=Nc[i])
if(vc[i]!=fa)build(vc[i],x);
}
void dfs(int x,int fa){
in[x]=++ts;st[ts][0]=x;
for(int i=head[x];i;i=Next[i]){
int y=ver[i],z=edge[i];
if(y==fa)continue;
d[y]=d[x]+z;
dfs(y,x);
}
++ts;
if(fa)st[ts][0]=fa;
}
void init(){
for(int i=2;i<M;i++)lg[i]=lg[i>>1]+1;
for(int j=1;(1<<j)<=ts;j++)
for(int i=1;i+(1<<j)-1<=ts;i++){
int x=st[i][j-1],y=st[i+(1<<(j-1))][j-1];
st[i][j]=(d[x]<d[y])?x:y;
}
}
int lca(int x,int y){
int l=in[x],r=in[y];
if(l>r)swap(l,r);int ln=lg[r-l+1];
return d[st[l][ln]]<d[st[r-(1<<ln)+1][ln]]?st[l][ln]:st[r-(1<<ln)+1][ln];
}
ll dist(int x,int y){
return d[x]+d[y]-2*d[lca(x,y)];
}
void get_size(int x,int fa){
sz[x]=1;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fa||vis[i])continue;
get_size(y,x);
sz[x]+=sz[y];
}
}
void get_mid(int x,int fa,int sum){
int siz=0;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fa||vis[i])continue;
get_mid(y,x,sum);
siz=max(siz,max(sz[y],sum-sz[y]));
if(siz<=maxpt)maxpt=siz,mid=i;
}
}
int copy(){
int p=++t;
l(p)=r(p)=e(p)=0;
lc(p)=rc(p)=0;
ld(p)=rd(p)=0;
return p;
}
int copy(int p){
tree[++t]=tree[p];
assert(t<=(N<<5));
return t;
}
void solve(int p,int i){
vis[i]=vis[i^1]=1;e(p)=i;
int ls=ver[i],rs=ver[i^1];
get_size(ls,rs);
s.pb(0);
l(p)=copy();
if(sz[ls]==1){
if(ls<=n)
for(int z:s)v[ls].pb(z);
}
else{
maxpt=B;
get_mid(ls,rs,sz[ls]);
solve(l(p),mid);
}
s.pop_back();
get_size(rs,ls);
s.pb(1);
r(p)=copy();
if(sz[rs]==1){
if(rs<=n)
for(int z:s)v[rs].pb(z);
}
else{
maxpt=B;
get_mid(rs,ls,sz[rs]);
solve(r(p),mid);
}
s.pop_back();
}
int insert(int p,int x,int dep){
p=copy(p);
if(dep==(int)v[x].size())return p;
if(!v[x][dep]){
l(p)=insert(l(p),x,dep+1);
lc(p)++;ld(p)+=dist(x,ver[e(p)]);
}
else{
r(p)=insert(r(p),x,dep+1);
rc(p)++;rd(p)+=dist(x,ver[e(p)^1]);
}
return p;
}
ll query(int u,int w,int x,int dep){
if(dep==(int)v[x].size())return 0;
ll val=0,len;
if(!v[x][dep]){
val+=query(l(u),l(w),x,dep+1);
len=dist(x,ver[e(u)^1]);
val+=len*(rc(u)-rc(w))+(rd(u)-rd(w));
}
else{
val+=query(r(u),r(w),x,dep+1);
len=dist(x,ver[e(u)]);
val+=len*(lc(u)-lc(w))+(ld(u)-ld(w));
}
return val;
}
int main(){
cnt=n=read();m=read();
for(int i=1;i<=n;i++)p[i]=read();
for(int i=1;i<n;i++){
int x=read(),y=read(),z=read();
ac(x,y,z),ac(y,x,z);
}
build(1,0);
dfs(1,0);init();
get_size(1,0);
maxpt=B;
get_mid(1,0,cnt);
rt[0]=copy();
solve(rt[0],mid);
for(int i=1;i<=n;i++)
rt[i]=insert(rt[i-1],p[i],0);
while(m--){
int op=read(),l,r,x;
if(op&1){
l=read()^lastans,r=read()^lastans,x=read()^lastans;
lastans=query(rt[r],rt[l-1],x,0);
printf("%lld\n",lastans);
lastans&=B;
}
else{
x=read()^lastans;
swap(p[x],p[x+1]);
rt[x]=insert(rt[x-1],p[x],0);
}
}
return 0;
}