动态开点线段树

Posted cmyg

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态开点线段树相关的知识,希望对你有一定的参考价值。

 

https://www.luogu.org/problemnew/show/P1908

 

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <cmath>
  4 #include <cstring>
  5 #include <string>
  6 #include <algorithm>
  7 #include <iostream>
  8 using namespace std;
  9 
 10 #define ll long long
 11 const double eps=1e-8;
 12 const int maxn=5e5+10;
 13 const int maxg=1.5e7+10;
 14 const int maxv=1e9;///最大数
 15 
 16 struct node
 17 {
 18     int l,r,sum,tag;
 19 }tr[maxg];
 20 ///[1,1e9] 30  30*5e5
 21 
 22 int num;
 23 
 24 inline void read(int &x)
 25 {
 26     char ch=getchar();
 27     while (ch<0 || ch>9)
 28         ch=getchar();
 29     x=0;
 30     while (ch>=0 && ch<=9)
 31         x=x*10+ch-0,ch=getchar();
 32 }
 33 
 34 void push_down(int ind)
 35 {
 36     if (tr[ind].l==0)
 37         tr[ind].l=++num;
 38     if (tr[ind].r==0)
 39         tr[ind].r=++num;
 40     tr[tr[ind].l].sum+=tr[ind].tag;
 41     tr[tr[ind].r].sum+=tr[ind].tag;
 42     tr[tr[ind].l].tag+=tr[ind].tag;
 43     tr[tr[ind].r].tag+=tr[ind].tag;
 44     tr[ind].tag=0;
 45 }
 46 
 47 void update(int ind,int l,int r,int x,int y)
 48 {
 49     if (x<=l && r<=y)
 50     {
 51         tr[ind].sum++;  ///+z
 52         tr[ind].tag++;
 53         return;
 54     }
 55 
 56     if (tr[ind].tag!=0)
 57         push_down(ind);
 58 
 59     int m=(l+r)>>1;
 60     if (x<=m)
 61     {
 62         if (tr[ind].l==0)
 63             tr[ind].l=++num;
 64         update(tr[ind].l,l,m,x,y);
 65     }
 66     if (m<y)
 67     {
 68         if (tr[ind].r==0)
 69             tr[ind].r=++num;
 70         update(tr[ind].r,m+1,r,x,y);
 71     }
 72     tr[ind].sum=tr[tr[ind].l].sum + tr[tr[ind].r].sum;
 73 }
 74 
 75 int query(int ind,int l,int r,int x,int y)
 76 {
 77     if (x<=l && r<=y)
 78         return tr[ind].sum;
 79     if (tr[ind].tag!=0)
 80         push_down(ind);
 81     int m=(l+r)>>1,sum=0;
 82     if (x<=m && tr[ind].l!=0)
 83         sum+=query(tr[ind].l,l,m,x,y);
 84     if (m<y && tr[ind].r!=0)
 85         sum+=query(tr[ind].r,m+1,r,x,y);
 86     tr[ind].sum=tr[tr[ind].l].sum + tr[tr[ind].r].sum;
 87     return sum;
 88 }
 89 
 90 int main()
 91 {
 92     int n,x,i;
 93     ll sum=0;
 94     num=1;///original 0 0 0
 95 
 96     read(n);
 97     for (i=1;i<=n;i++)
 98     {
 99         read(x);
100         sum+=i-1-query(1,1,maxv,1,x);
101         update(1,1,maxv,x,x);
102     }
103     printf("%lld",sum);
104     return 0;
105 }

 

以上是关于动态开点线段树的主要内容,如果未能解决你的问题,请参考以下文章

线段树 动态开点

HDU6183 Color it (线段树动态开点)

动态开点线段树

「模板」线段树静态开点(单点+区间修改)动态开点

HDU - 6183 Color it(动态开点线段树/树状数组套动态开点线段树)

HDU - 6183 动态开点线段树 || 令人绝望的线段树