想到离线之后就很裸了。。。
我承认自己是SB 一开始还没想到。。。。
还有。。今天每次提交都会忘了删文件。。。。。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
using namespace std;
char c;
inline void read(int &a)
{
a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
const
int mod=201314;
struct Segement{
int l,r,data;
int flag;
}Segement_Tree[1000001];
void Segement_Tree_Build(int place,int l,int r)
{
Segement_Tree[place].r=r;
Segement_Tree[place].l=l;
if(l^r)
Segement_Tree_Build(place<<1,l,(l+r)>>1), Segement_Tree_Build(place<<1|1,((l+r)>>1)+1,r);
Segement_Tree[place].flag=0;
Segement_Tree[place].data=0;
}
inline void Segement_Tree_Pushdown(int place)
{
Segement_Tree[place].data+=(Segement_Tree[place].r-Segement_Tree[place].l+1)*Segement_Tree[place].flag;
Segement_Tree[place].data%=mod;
if(Segement_Tree[place].l^Segement_Tree[place].r)
Segement_Tree[place<<1].flag+=Segement_Tree[place].flag,Segement_Tree[place<<1].flag%=mod, Segement_Tree[place<<1|1].flag+=Segement_Tree[place].flag, Segement_Tree[place<<1|1].flag%=mod;
Segement_Tree[place].flag=0;
}
int Segement_Tree_Query(int place,int l,int r)
{
if(Segement_Tree[place].flag)
Segement_Tree_Pushdown(place);
if(l<=Segement_Tree[place].l&&r>=Segement_Tree[place].r)
return Segement_Tree[place].data;
int data=0;
if(l<=Segement_Tree[place<<1].r)
data+=Segement_Tree_Query(place<<1,l,r);
if(r>=Segement_Tree[place<<1|1].l)
data+=Segement_Tree_Query(place<<1|1,l,r);
return data%mod;
}
void Segement_Tree_Add(int place,int l,int r)//1
{
if(l<=Segement_Tree[place].l&&r>=Segement_Tree[place].r)
{Segement_Tree[place].flag++;Segement_Tree[place].flag%=mod;return ;}
Segement_Tree[place].data+=(min(r,Segement_Tree[place].r)-max(l,Segement_Tree[place].l)+1);
if(l<=Segement_Tree[place<<1].r)
Segement_Tree_Add(place<<1,l,r);
if(r>=Segement_Tree[place<<1|1].l)
Segement_Tree_Add(place<<1|1,l,r);
}
int Heavy_Chain_Begin[1000001],Heavy_Chain_Place[1000001],Heavy_Chain_End[1000001],Heavy_Chain_Node[1000001];
int Heavy_Con,Heavy_Son[1000001];
struct Chain
{
int other;
Chain *next;
Chain(){next=NULL;}
}*Son[1000001],*Head[1000001];
int f[1000001];
int Con[1000001];
int DFS1(int u)
{
Chain *ad;
Con[u]++;
Heavy_Son[u]=0;
for(Chain *tp=Head[u];tp;tp=tp->next)
if(tp->other!=f[u])
{
f[tp->other]=u;
ad=new Chain;
ad->other=tp->other;
ad->next=Son[u];
Son[u]=ad;
DFS1(tp->other);
if(Con[tp->other]>Con[Heavy_Son[u]])
Heavy_Son[u]=tp->other;
Con[u]+=Con[tp->other];
}
}
int DFS2(int u,int f)
{
Heavy_Chain_Begin[u]=f;
Heavy_Chain_Place[u]=++Heavy_Con;
Heavy_Chain_Node[Heavy_Con]=u;
if(Heavy_Son[u])
{
DFS2(Heavy_Son[u],f);
for(Chain *tp=Son[u];tp;tp=tp->next)
if(tp->other!=Heavy_Son[u])
DFS2(tp->other,Heavy_Con+1);
}
Heavy_Chain_End[u]=Heavy_Con;
}
inline void addside(int a,int b)
{
Chain *tp=new Chain;tp->next=Head[a],tp->other=b;
Head[a]=tp;
}
struct oper
{
bool end;
int place;
int num;
int z;
int ans;
inline friend bool operator <(oper a,oper b)
{ return a.place<b.place;}
}line[1000001];
inline bool cmp(const oper &a,const oper &b)
{
return a.num<b.num||(a.num==b.num&&a.end);
}
inline void Add(int u)
{
if(u==0)
return ;
while(Heavy_Chain_Begin[u]!=1)
{
Segement_Tree_Add(1,Heavy_Chain_Begin[u],Heavy_Chain_Place[u]);
u=f[Heavy_Chain_Node[Heavy_Chain_Begin[u]]];
}
Segement_Tree_Add(1,Heavy_Chain_Begin[u],Heavy_Chain_Place[u]);
}
inline int Query(int u)
{
int res=0;
if(u==0)
return 0;
while(Heavy_Chain_Begin[u]!=1)
{
res+=Segement_Tree_Query(1,Heavy_Chain_Begin[u],Heavy_Chain_Place[u]);
u=f[Heavy_Chain_Node[Heavy_Chain_Begin[u]]];
}
res+=Segement_Tree_Query(1,Heavy_Chain_Begin[u],Heavy_Chain_Place[u]);
return res;
}
int main()
{
int i,j,k,l,n,m,r;
read(n),read(m);
for(i=2;i<=n;i++)
read(f[i]),f[i]++,addside(f[i],i),addside(i,f[i]);
DFS1(1),DFS2(1,1);
Segement_Tree_Build(1,1,Heavy_Con);
for(i=1;i<=m;i++)
{
read(l),read(r);
line[(i<<1)-1].end=false;
line[(i<<1)-1].place=r+1;
line[i<<1].end=true;
line[i<<1].place=l;
line[(i<<1)-1].num=line[(i<<1)].num=i;
read(k);
line[(i<<1)-1].z=line[(i<<1)].z=k+1;
}
sort(line+1,line+1+(m<<1));
int last=1;
m<<=1;
for(i=1;i<=m;i++)
{
if(line[i].place>=last)
for(last;last<=line[i].place;last++)
Add(last);
line[i].ans=Query(line[i].z)%mod;
}
m>>=1;
sort(line+1,line+1+(m<<1),cmp);
for(i=1;i<=m;i++)
printf("%d\n",(mod+(line[i<<1].ans-line[(i<<1)-1].ans)%mod)%mod);
}