想到离线之后就很裸了。。。
我承认自己是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); }