zoukankan      html  css  js  c++  java
  • 题解 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('
    ');
    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 }
  • 相关阅读:
    HDU 3572 Task Schedule(拆点+最大流dinic)
    POJ 1236 Network of Schools(Tarjan缩点)
    HDU 3605 Escape(状压+最大流)
    HDU 1166 敌兵布阵(分块)
    Leetcode 223 Rectangle Area
    Leetcode 219 Contains Duplicate II STL
    Leetcode 36 Valid Sudoku
    Leetcode 88 Merge Sorted Array STL
    Leetcode 160 Intersection of Two Linked Lists 单向链表
    Leetcode 111 Minimum Depth of Binary Tree 二叉树
  • 原文地址:https://www.cnblogs.com/ilverene/p/9850323.html
Copyright © 2011-2022 走看看