题目:传送门
这道题根本不用lca,也没有部分分。。。
考虑求两个点xy的lca的深度。
我们将x到树根所有点的值都加1,然后查询y到根的和,其实就是lca的深度。
所以本题离线一下上树剖乱搞就可以了。
AC代码如下:
718ms 17348Kib
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <algorithm> 5 6 using namespace std; 7 8 namespace StandardIO { 9 10 template<typename T> inline void read (T &x) { 11 x=0;T f=1;char c=getchar(); 12 for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1; 13 for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0'; 14 x*=f; 15 } 16 template<typename T> inline void write (T x) { 17 if (x<0) putchar('-'),x=-x; 18 if (x>=10) write(x/10); 19 putchar(x%10+'0'); 20 } 21 22 } 23 24 using namespace StandardIO; 25 26 namespace Solve { 27 28 const int MOD=201314; 29 const int N=500500; 30 31 struct Tree { 32 int tree[N*4],tag[N*4]; 33 void pushdown (int pos,int left,int right) { 34 if (tag[pos]) { 35 int mid=(left+right)/2; 36 tree[pos*2]+=(mid-left+1)*tag[pos],tree[pos*2]%=MOD; 37 tree[pos*2+1]+=(right-mid)*tag[pos],tree[pos*2+1]%=MOD; 38 tag[pos*2]+=tag[pos],tag[pos*2+1]+=tag[pos],tag[pos*2]%=MOD,tag[pos*2+1]%=MOD; 39 tag[pos]=0; 40 } 41 } 42 void pushup (int pos) { 43 tree[pos]=tree[pos*2]+tree[pos*2+1],tree[pos]%=MOD; 44 } 45 void update (int pos,int left,int right,int L,int R,int add) { 46 if (L<=left&&right<=R) { 47 tree[pos]+=add*(right-left+1),tree[pos]%=MOD; 48 tag[pos]+=add,tag[pos]%=MOD; 49 return; 50 } 51 pushdown(pos,left,right); 52 int mid=(left+right)/2; 53 if (L<=mid) update(pos*2,left,mid,L,R,add); 54 if (R>mid) update(pos*2+1,mid+1,right,L,R,add); 55 pushup(pos); 56 } 57 int query (int pos,int left,int right,int L,int R) { 58 if (L<=left&&right<=R) return tree[pos]; 59 pushdown(pos,left,right); 60 int mid=(left+right)/2; 61 int ans=0; 62 if (L<=mid) ans+=query(pos*2,left,mid,L,R),ans%=MOD; 63 if (R>mid) ans+=query(pos*2+1,mid+1,right,L,R),ans%=MOD; 64 return ans; 65 } 66 } ljz; 67 int n,q; 68 vector<int>M[N]; 69 int dep[N],siz[N],fa[N],son[N]; 70 int ind[N],cnt; 71 int top[N]; 72 73 void dfs1 (int now,int father) { 74 dep[now]=dep[father]+1,fa[now]=father,siz[now]=1; 75 for (register vector<int>::iterator i=M[now].begin(); i!=M[now].end(); i++) { 76 if(*i==father) continue; 77 dfs1(*i,now); 78 siz[now]+=siz[*i]; 79 if (siz[*i]>siz[son[now]]) son[now]=*i; 80 } 81 } 82 void dfs2(int now,int tp){ 83 top[now]=tp,ind[now]=++cnt; 84 if (son[now]) dfs2(son[now],tp); 85 for (register vector<int>::iterator i=M[now].begin(); i!=M[now].end(); i++) { 86 if (*i==fa[now]||*i==son[now]) continue; 87 dfs2(*i,*i); 88 } 89 } 90 void upd (int x,int add){ 91 while (x) { 92 ljz.update(1,1,n,ind[top[x]],ind[x],add); 93 x=fa[top[x]]; 94 } 95 } 96 int que (int x) { 97 int ans=0; 98 while (x) { 99 ans+=ljz.query(1,1,n,ind[top[x]],ind[x]),ans%=MOD; 100 x=fa[top[x]]; 101 } 102 return ans; 103 } 104 int A[N]; 105 struct Q{ 106 int val,ind; 107 Q () {val=ind=0;} 108 Q (int a,int b) :val(a),ind(b) {} 109 friend bool operator < (Q a,Q b) { 110 return a.val<b.val; 111 } 112 } s1[N],s2[N]; 113 int a1=1,a2=1; 114 int Ans[N]; 115 116 inline void solve () { 117 read(n),read(q); 118 for (register int i=2; i<=n; i++) { 119 int a; 120 read(a); 121 M[a+1].push_back(i); 122 } 123 dfs1(1,0); 124 dfs2(1,0); 125 for (register int i=1; i<=q; i++) { 126 int a,b,c; 127 read(a),read(b),read(c); 128 a++,b++,c++; 129 A[i]=c; 130 s1[i]=Q(a-1,i),s2[i]=Q(b,i); 131 } 132 sort(s1+1,s1+q+1); 133 sort(s2+1,s2+q+1); 134 while (s1[a1].val==0) a1++; 135 for (register int i=1; i<=n; i++) { 136 upd(i,1); 137 while (s1[a1].val==i) { 138 Ans[s1[a1].ind]-=que(A[s1[a1].ind])-MOD,Ans[s1[a1].ind]%=MOD; 139 a1++; 140 } 141 while (s2[a2].val==i) { 142 Ans[s2[a2].ind]+=que(A[s2[a2].ind]),Ans[s2[a2].ind]%=MOD; 143 a2++; 144 } 145 } 146 for (register int i=1; i<=q; i++) { 147 write(Ans[i]),putchar(' '); 148 } 149 } 150 151 } 152 153 using namespace Solve; 154 155 int main () { 156 // freopen(".in","r",stdin); 157 // freopen(".out","w",stdout); 158 solve(); 159 }