https://www.luogu.org/problemnew/show/P1823
自己只会一个log的
设取的人的位置分别是l,r(l<r)
这个做法大概是考虑枚举r,设法对于每个r求出有多少个满足的l
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define fi first 7 #define se second 8 #define mp make_pair 9 #define pb push_back 10 typedef long long ll; 11 typedef unsigned long long ull; 12 ll n; 13 ll d[500100]; 14 #define lowbit(x) ((x)&(-x)) 15 void add(ll p,ll x) 16 { 17 for(;p<=n;p+=lowbit(p)) 18 d[p]+=x; 19 } 20 ll sum(ll p) 21 { 22 ll an=0; 23 for(;p>0;p-=lowbit(p)) 24 an+=d[p]; 25 return an; 26 } 27 ll a[500100]; 28 ll st[500010],tp; 29 ll pre[500010]; 30 ll ans; 31 int main() 32 { 33 ll i; 34 scanf("%lld",&n); 35 for(i=1;i<=n;++i) 36 scanf("%lld",&a[i]); 37 for(i=n;i>=1;--i) 38 { 39 while(tp&&a[st[tp]]<a[i]) pre[st[tp--]]=i; 40 st[++tp]=i; 41 } 42 //for(i=1;i<=n;++i) 43 // printf("1t%lld ",pre[i]); 44 tp=0; 45 for(i=1;i<=n;++i) 46 { 47 ans+=sum(i-1); 48 if(pre[i]) ans-=sum(pre[i]-1); 49 while(tp&&a[st[tp]]<a[i]) 50 { 51 add(st[tp],-1); 52 --tp; 53 } 54 st[++tp]=i;add(st[tp],1); 55 } 56 printf("%lld",ans); 57 return 0; 58 }
题解有高明的O(n)做法