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 }
  • 相关阅读:
    Linux中ctrl+z 、ctrl+c、 ctrl+d区别
    linux文件与用户权限的设置
    查找jdk的安装目录
    linux上修改防火墙操作
    linux上打包与压缩操作
    安装hive操作参考视频
    linux上设置环境变量每次需要source /etc/profile问题处理
    【c语言趣味编程100例】出售金鱼
    【c语言趣味编程100例】三色球问题
    【c语言】递归实现strlen()函数
  • 原文地址:https://www.cnblogs.com/ilverene/p/9850323.html
Copyright © 2011-2022 走看看