10.21T5 二分+线段树
Description
Input
6
10
3
7
4
12
2
10
3
7
4
12
2
Output
5
对每个位置二分后面的位置,找出恰好没有高于自己的点加起来就可以了,用线段树维护最大值
code:
1 #include<iostream> 2 #include<cstdio> 3 #define N 1000005 4 #define lc (p<<1) 5 #define rc (p<<1|1) 6 using namespace std; 7 long long a[N]; 8 struct node{ 9 long long l,r,max; 10 }t[N]; 11 void pushup(long long p){ 12 t[p].max=max(t[lc].max,t[rc].max); 13 } 14 void build(long long p,long long l,long long r){ 15 t[p].l=l,t[p].r=r; 16 if(l==r){ 17 t[p].max=a[l]; 18 return; 19 } 20 long long mid=l+r>>1; 21 build(lc,l,mid); 22 build(rc,mid+1,r); 23 pushup(p); 24 } 25 long long query(long long p,long long ql,long long qr){ 26 if(ql<=t[p].l&&t[p].r<=qr){ 27 return t[p].max; 28 } 29 long long ans=0; 30 long long mid=t[p].l+t[p].r>>1; 31 if(ql<=mid)ans=max(ans,query(lc,ql,qr)); 32 if(qr>mid)ans=max(ans,query(rc,ql,qr)); 33 return ans; 34 } 35 int main(){ 36 long long n; 37 cin>>n; 38 for(long long i=1;i<=n;i++){ 39 cin>>a[i]; 40 } 41 build(1,1,n); 42 long long tot=0; 43 for(long long i=1;i<=n;i++){ 44 long long l=i,r=n,ans=0; 45 while(l<=r){ 46 long long mid=l+r>>1; 47 if(query(1,i+1,mid)<a[i])l=mid+1,ans=mid; 48 else r=mid-1; 49 } 50 tot+=ans-i; 51 } 52 cout<<tot; 53 }
over