洛谷P1823 [COI2007] Patrik 音乐会的等待

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\n",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 }
View Code

题解有高明的O(n)做法

 

posted @ 2018-10-28 20:42  hehe_54321  阅读(215)  评论(0编辑  收藏  举报
AmazingCounters.com