题解 LNOI2014 LCA

题目:传送门


这道题根本不用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('\n');
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 }

猜你喜欢

转载自www.cnblogs.com/ilverene/p/9850323.html
今日推荐