百度空间马上要下架的说,赶快把最后一点题解补完,然后搬家
这是一道不错的题,首先注意询问是满足区间减法的,我们把他变成前缀和表示
设我们询问[1,r]中的点和z的LCA深度和,假设我们确定一个根,不难发现一个有趣的事情
点z和点i的LCA深度=z和i到根公共路径(LCA到根的路径)上点的个数!
也就是说,当我们查询时,我们只要知道,[1,r]上的点到根路径上的点在z到根上出现的次数和
所以不难想到离线的做法,按照编号的顺序,每次做到点i,就把点i到根路径上点权值+1
询问的时候我们只要查询z到根路径上点权值和即可,显然我们可以用树链剖分+线段树维护

  1 const mo=201314;
  2 type node=record
  3        po,next:longint;
  4      end;
  5      que=record
  6        x,y,p,op:longint;
  7      end;
  8 
  9 var p,c,top,ans,fa,size:array[0..50010] of longint;
 10     tree,lazy:array[0..50010*4] of longint;
 11     q:array[0..100010] of que;
 12     e:array[0..50010] of node;
 13     t,l,r,x,i,j,n,m:longint;
 14 
 15 procedure swap(var a,b:que);
 16   var c:que;
 17   begin
 18     c:=a;
 19     a:=b;
 20     b:=c;
 21   end;
 22 
 23 procedure add(x,y:longint);
 24   begin
 25     e[i].po:=y;
 26     e[i].next:=p[x];
 27     p[x]:=i;
 28   end;
 29 
 30 procedure dfs1(x:longint);
 31   var i,y:longint;
 32   begin
 33     size[x]:=1;
 34     i:=p[x];
 35     while i<>0 do
 36     begin
 37       y:=e[i].po;
 38       fa[y]:=x;
 39       dfs1(y);
 40       size[x]:=size[x]+size[y];
 41       i:=e[i].next;
 42     end;
 43   end;
 44 
 45 procedure dfs2(x:longint);
 46   var i,y,q:longint;
 47   begin
 48     inc(t);
 49     c[x]:=t;
 50     q:=n+1;
 51     i:=p[x];
 52     while i<>0 do
 53     begin
 54       y:=e[i].po;
 55       if size[y]>size[q] then q:=y;
 56       i:=e[i].next;
 57     end;
 58     if q<>n+1 then
 59     begin
 60       top[q]:=top[x];
 61       dfs2(q);
 62     end;
 63     i:=p[x];
 64     while i<>0 do
 65     begin
 66       y:=e[i].po;
 67       if y<>q then
 68       begin
 69         top[y]:=y;
 70         dfs2(y);
 71       end;
 72       i:=e[i].next;
 73     end;
 74   end;
 75 
 76 procedure sort(l,r:longint);
 77   var i,j,y:longint;
 78   begin
 79     i:=l;
 80     j:=r;
 81     y:=q[(l+r) shr 1].y;
 82     repeat
 83       while q[i].y<y do inc(i);
 84       while y<q[j].y do dec(j);
 85       if not(i>j) then
 86       begin
 87         swap(q[i],q[j]);
 88         inc(i);
 89         dec(j);
 90       end;
 91     until i>j;
 92     if l<j then sort(l,j);
 93     if i<r then sort(i,r);
 94   end;
 95 
 96 procedure push(i,l,r:longint);
 97   var m:longint;
 98   begin
 99     m:=(l+r) shr 1;
100     tree[i*2]:=tree[i*2]+lazy[i]*(m+1-l);
101     tree[i*2+1]:=tree[i*2+1]+lazy[i]*(r-m);
102     inc(lazy[i*2],lazy[i]);
103     inc(lazy[i*2+1],lazy[i]);
104     lazy[i]:=0;
105   end;
106 
107 procedure work(i,l,r,x,y:longint);
108   var m:longint;
109   begin
110     if (x<=l) and (y>=r) then
111     begin
112       tree[i]:=tree[i]+r-l+1;
113       lazy[i]:=lazy[i]+1;
114     end
115     else begin
116       if lazy[i]>0 then push(i,l,r);
117       m:=(l+r) shr 1;
118       if x<=m then work(i*2,l,m,x,y);
119       if y>m then work(i*2+1,m+1,r,x,y);
120       tree[i]:=(tree[i*2]+tree[i*2+1]) mod mo;
121     end;
122   end;
123 
124 function getans(i,l,r,x,y:longint):longint;
125   var m,s:longint;
126   begin
127     if (x<=l) and (y>=r) then exit(tree[i])
128     else begin
129       if lazy[i]>0 then push(i,l,r);
130       m:=(l+r) shr 1;
131       s:=0;
132       if x<=m then s:=s+getans(i*2,l,m,x,y);
133       if y>m then s:=s+getans(i*2+1,m+1,r,x,y);
134       exit(s);
135     end;
136   end;
137 
138 procedure ins(x:longint);
139   begin
140     while top[x]<>-1 do
141     begin
142       work(1,1,n,c[top[x]],c[x]);
143       x:=fa[top[x]];
144     end;
145     work(1,1,n,1,c[x]);
146   end;
147 
148 function ask(x:longint):longint;
149   begin
150     ask:=0;
151     while top[x]<>-1 do
152     begin
153       ask:=ask+getans(1,1,n,c[top[x]],c[x]);
154       x:=fa[top[x]];
155     end;
156     ask:=(ask+getans(1,1,n,1,c[x])) mod mo;
157   end;
158 
159 begin
160   readln(n,m);
161   for i:=1 to n-1 do
162   begin
163     read(x);
164     add(x,i);
165   end;
166   dfs1(0);
167   top[0]:=-1;
168   dfs2(0);
169   t:=0;
170   for i:=1 to m do
171   begin
172     readln(l,r,x);
173     inc(t);
174     q[t].x:=x; q[t].y:=l-1;
175     q[t].p:=i; q[t].op:=-1;
176     inc(t);
177     q[t].x:=x; q[t].y:=r;
178     q[t].p:=i; q[t].op:=1;
179   end;
180   sort(1,t);
181   j:=0;
182   for i:=1 to t do
183   begin
184     while (j<n) and (j<=q[i].y) do
185     begin
186       ins(j);
187       inc(j);
188     end;
189     ans[q[i].p]:=(ans[q[i].p]+q[i].op*ask(q[i].x)+mo) mod mo;
190   end;
191   for i:=1 to m do
192     writeln(ans[i]);
193 end.
View Code

 

posted on 2015-04-10 12:07  acphile  阅读(197)  评论(0编辑  收藏  举报