# bzoj3626 [ LNOI2014 ] -- 树链剖分

 1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #include<vector>
6 using namespace std;
7 #define N 50010
8 #define M 201314
9 #define ll long long
10 vector<int>g[N];
11 struct Node{
12     int f,z,d;
13     Node(){}
14     Node(int f,int z,int d):f(f),z(z),d(d){}
15 };
16 vector<Node>G[N];
17 int i,j,k,n,m,Top[N],Num,s[N],Son[N],w[N],c[N<<2],x,y,z,Ans[N],p[N<<2],f[N];
18 inline void Dfs1(int x){
19     s[x]=1;
20     for(int i=0;i<g[x].size();i++){
21         Dfs1(g[x][i]);
22         s[x]+=s[g[x][i]];
23         if(s[g[x][i]]>s[Son[x]])Son[x]=g[x][i];
24     }
25 }
26 inline void Dfs2(int x,int Tmp){
27     Top[x]=Tmp;w[x]=++Num;
28     if(Son[x])Dfs2(Son[x],Tmp);
29     for(int i=0;i<g[x].size();i++)
30     if(g[x][i]!=Son[x])Dfs2(g[x][i],g[x][i]);
31 }
32 inline void Down(int x,int y){
33     p[x<<1]+=p[x];p[x<<1|1]+=p[x];
34     c[x<<1]+=p[x]*(y+1>>1);c[x<<1|1]+=p[x]*(y>>1);
35     p[x]=0;
36 }
37 inline void Up(int x){c[x]=c[x<<1]+c[x<<1|1];}
38 inline void Update(int Node,int l,int r,int L,int R){
39     if(l>R||r<L)return;
40     if(l>=L&&r<=R){
41         c[Node]+=r-l+1;
42         p[Node]++;
43         return;
44     }
45     if(p[Node])Down(Node,r-l+1);
46     int Mid=l+r>>1;
47     Update(Node<<1,l,Mid,L,R);
48     Update(Node<<1|1,Mid+1,r,L,R);
49     Up(Node);
50 }
51 inline int Query(int Node,int l,int r,int L,int R){
52     if(l>R||r<L)return 0;
53     if(l>=L&&r<=R)return c[Node];
54     if(p[Node])Down(Node,r-l+1);
55     int Mid=l+r>>1;
56     return (Query(Node<<1,l,Mid,L,R)+Query(Node<<1|1,Mid+1,r,L,R))%M;
57 }
58 inline void Update_tree(int x){
59     while(x){
60         Update(1,1,n,w[Top[x]],w[x]);
61         x=f[Top[x]];
62     }
63 }
64 inline int Query_tree(int x){
65     int Ans=0;
66     while(x){
67         Ans=(Ans+Query(1,1,n,w[Top[x]],w[x]))%M;
68         x=f[Top[x]];
69     }
70     return Ans;
71 }
72 int main(){
73     scanf("%d%d",&n,&m);
74     for(i=2;i<=n;i++)scanf("%d",&f[i]),g[++f[i]].push_back(i);
75     Dfs1(1);Dfs2(1,1);
76     for(i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&z),G[x].push_back(Node(i,++z,-1)),G[y+1].push_back(Node(i,z,1));
77     for(i=1;i<=n;i++){
78         Update_tree(i);
79         for(j=0;j<G[i].size();j++){
80             Ans[G[i][j].f]+=Query_tree(G[i][j].z)*G[i][j].d;
81         }
82     }
83     for(i=1;i<=m;i++)printf("%d\n",(Ans[i]+M)%M);
84     return 0;
85 }
bzoj3626

posted @ 2017-05-13 09:34  gjghfd  阅读(248)  评论(0编辑  收藏  举报