zoukankan      html  css  js  c++  java
  • bzoj 3626: [LNOI2014]LCA

    把区间排序,可以发现直接往点上到根搞一下值(每来一个数,路径上就加1),那么最后的答案可以差分一下,而且deep[lca]就可以直接查询z点到根的和。

      1 #include<bits/stdc++.h>
      2 #define N 200005
      3 #define LL long long
      4 #define inf 0x3f3f3f3f
      5 using namespace std;
      6 inline int ra()
      7 {
      8     int x=0,f=1; char ch=getchar();
      9     while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
     10     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
     11     return x*f;
     12 }
     13 const int mod=201314;
     14 struct data{int id,p; bool flag;} a[N];
     15 struct seg{int size,tag,sum,l,r;} t[N<<1];
     16 struct node{int ans1,ans2,z;} q[N];
     17 struct edge{int next,to;} e[N];
     18 int n,m,cnt,dfn; 
     19 int son[50005],head[50005],fa[50005],belong[50005],pl[50005],deep[50005];
     20 bool cmp(data a, data b) {return a.p<b.p;}
     21 void insert(int x, int y){e[++cnt].next=head[x]; e[cnt].to=y; head[x]=cnt;}
     22 void dfs1(int x)
     23 {
     24     son[x]=1;
     25     for (int i=head[x];i;i=e[i].next)
     26     {
     27         if (e[i].to==fa[x]) continue;
     28         deep[e[i].to]=deep[x]+1;
     29         fa[e[i].to]=x;
     30         dfs1(e[i].to);
     31         son[x]+=son[e[i].to];
     32     }
     33 }
     34 void dfs2(int x, int chain)
     35 {
     36     belong[x]=chain; pl[x]=++dfn;
     37     int k=n;
     38     for (int i=head[x];i;i=e[i].next)
     39         if (e[i].to!=fa[x] && son[e[i].to]>son[k])
     40             k=e[i].to;
     41     if (k!=n) dfs2(k,chain);
     42     for (int i=head[x];i;i=e[i].next)
     43         if (e[i].to!=fa[x] && e[i].to!=k)
     44             dfs2(e[i].to,e[i].to);
     45 }
     46 void pushdown(int k)
     47 {
     48     if (t[k].l==t[k].r || !t[k].tag) return;
     49     int tmp=t[k].tag%mod; t[k].tag=0;
     50     t[k<<1].sum+=t[k<<1].size*tmp;
     51     t[k<<1|1].sum+=t[k<<1|1].size*tmp;
     52     t[k<<1].tag+=tmp; t[k<<1|1].tag+=tmp;
     53 }
     54 void update(int k)
     55 {
     56     t[k].sum=t[k<<1].sum+t[k<<1|1].sum; t[k].sum%=mod;
     57 }
     58 void build(int k, int l, int r)
     59 {
     60     t[k].l=l; t[k].r=r; t[k].size=r-l+1;
     61     if (l==r) return;
     62     int mid=l+r>>1;
     63     build(k<<1,l,mid); build(k<<1|1,mid+1,r);
     64 }
     65 void change(int k, int x, int y)
     66 {
     67     pushdown(k);
     68     int l=t[k].l,r=t[k].r;
     69     if (l==x && y==r)
     70     {
     71         t[k].tag++; t[k].sum+=t[k].size;
     72         return;
     73     }
     74     int mid=l+r>>1;
     75     if (y<=mid) change(k<<1,x,y);
     76     else if (x>mid) change(k<<1|1,x,y);
     77     else {
     78         change(k<<1,x,mid); change(k<<1|1,mid+1,y);
     79     }
     80     update(k);
     81 }
     82 int ask(int k, int x, int y)
     83 {
     84     pushdown(k);
     85     int l=t[k].l,r=t[k].r;
     86     if (l==x && y==r) return t[k].sum;
     87     int mid=l+r>>1;
     88     if (y<=mid) return ask(k<<1,x,y);
     89     else if (x>mid) return ask(k<<1|1,x,y);
     90     else return ask(k<<1,x,mid)+ask(k<<1|1,mid+1,y); 
     91 }
     92 void solve_change(int x, int y)
     93 {
     94     while (belong[x]!=belong[y])
     95     {
     96         change(1,pl[belong[x]],pl[x]);
     97         x=fa[belong[x]];
     98     }
     99     change(1,pl[y],pl[x]);
    100 }
    101 int solve_ask(int x, int y)
    102 {
    103     int sum=0;
    104     while (belong[x]!=belong[y])
    105     {
    106         sum+=ask(1,pl[belong[x]],pl[x])%mod;
    107         sum%=mod;
    108         x=fa[belong[x]];
    109     }
    110     sum+=ask(1,pl[y],pl[x]); sum%=mod;
    111     return sum;
    112 }
    113 int main()
    114 {
    115     n=ra(); m=ra();
    116     for (int i=1; i<n; i++) insert(ra(),i);
    117     int tot=0;
    118     for (int i=1; i<=m; i++)
    119     {
    120         int l=ra(),r=ra(); q[i].z=ra();
    121         a[++tot].p=l-1; a[tot].id=i; a[tot].flag=0;
    122         a[++tot].p=r; a[tot].id=i; a[tot].flag=1;
    123     }
    124     build(1,1,n);
    125     sort(a+1,a+tot+1,cmp);
    126     dfs1(0); dfs2(0,0); 
    127     int now=-1;
    128     for (int i=1; i<=tot; i++)
    129     {
    130         while (now<a[i].p)
    131         {
    132             now++;
    133             solve_change(now,0);
    134         }
    135         int t=a[i].id;
    136         if (!a[i].flag) q[t].ans1=solve_ask(q[t].z,0);
    137         else q[t].ans2=solve_ask(q[t].z,0);
    138     }
    139     for (int i=1; i<=m; i++)
    140         printf("%d
    ",(q[i].ans2-q[i].ans1+mod)%mod);
    141     return 0;
    142 }
  • 相关阅读:
    LeetCode-求最长回文子序列
    C++四种类型转换总结
    kmp算法分析和C++实现
    把二叉树打印成多行
    考研数据结构笔记—堆排序
    天勤考研数据结构笔记—栈的C语言实现
    合并两个排序的链表递归和非递归C++实现
    二叉树的线索化
    单链表的基本操作实现
    OpenFaceswap 入门教程(3): 软件参数篇!
  • 原文地址:https://www.cnblogs.com/ccd2333/p/6482493.html
Copyright © 2011-2022 走看看