rt,树剖部分粘的板子。
#include<bits/stdc++.h>
#define int long long
#define ls u*2
#define rs u*2+1
using namespace std;
const int N=1e5+1,p=201314;
int n,m,u,v,z,b[4*N],lz[4*N],cnt,l,r=1,fa[N],d[N],son[N],sz[N],tp[N],dfn[N],rev[N],ans[N];
vector<int>G[N];
struct node{
int id,x,z,op;
}q[N];
bool cmp(node x,node y){
return x.x<y.x;
}
void dfs1(int u){
son[u]=-1;
sz[u]=1;
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(v!=fa[u]){
d[v]=d[u]+1;
fa[v]=u;
dfs1(v);
sz[u]+=sz[v];
if(son[u]==-1||sz[v]>sz[son[u]]) son[u]=v;
}
}
}
void dfs2(int u,int t){
tp[u]=t;
dfn[u]=++cnt;
rev[cnt]=u;
if(son[u]==-1) return;
dfs2(son[u],t);
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(v!=son[u]&&v!=fa[u]) dfs2(v,v);
}
}
void upd(int u,int l,int r){
int mid=l+r>>1;
(b[ls]+=lz[u]*(mid-l+1))%=p;
(b[rs]+=lz[u]*(r-mid))%=p;
(lz[ls]+=lz[u])%=p;
(lz[rs]+=lz[u])%=p;
lz[u]=0;
}
void add(int u,int l,int r,int L,int R,int k){
if(L<=l&&r<=R){
(b[u]+=k*(r-l+1))%=p;
(lz[u]+=k)%=p;
return;
}
upd(u,l,r);
int mid=l+r>>1;
if(L<=mid) add(ls,l,mid,L,R,k);
if(R>mid) add(rs,mid+1,r,L,R,k);
b[u]=(b[ls]+b[rs])%p;
}
int qsum(int u,int l,int r,int L,int R){
if(L<=l&&r<=R) return b[u];
upd(u,l,r);
int mid=l+r>>1,ans=0;
if(L<=mid) (ans+=qsum(ls,l,mid,L,R))%=p;
if(R>mid) (ans+=qsum(rs,mid+1,r,L,R))%=p;
return ans;
}
void addlca(int x,int y,int k){
while(tp[x]!=tp[y]){
if(d[tp[x]]<d[tp[y]]) swap(x,y);
add(1,1,n,dfn[tp[x]],dfn[x],k);
x=fa[tp[x]];
}
if(d[x]>d[y]) swap(x,y);
add(1,1,n,dfn[x],dfn[y],k);
}
int qlca(int x,int y){
int ans=0;
while(tp[x]!=tp[y]){
if(d[tp[x]]<d[tp[y]]) swap(x,y);
(ans+=qsum(1,1,n,dfn[tp[x]],dfn[x]))%=p;
x=fa[tp[x]];
}
if(d[x]>d[y]) swap(x,y);
(ans+=qsum(1,1,n,dfn[x],dfn[y]))%=p;
return ans;
}
signed main(){
cin>>n>>m;
for(int i=2;i<=n;i++){
cin>>u;
u++;
G[u].push_back(i);
G[i].push_back(u);
}
dfs1(1);
dfs2(1,1);
for(int i=1;i<=m;i++){
cin>>u>>v>>z;
v++,z++;
q[++l]={i,u,z,0};
q[++l]={i,v,z,1};
}
sort(q+1,q+1+l,cmp);
for(int i=1;i<=l;i++){
for(;r<=q[i].x;r++) addlca(1,r,d[r]);
if(q[i].op) ans[q[i].id]+=qlca(1,q[i].z);
else ans[q[i].id]-=qlca(1,q[i].z);
}
for(int i=1;i<=m;i++) cout<<(ans[i]+p)%p<<endl;
}