动态开点线段树
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 }