[Usaco2006 Nov]Bad Hair Day 乱发节

时间:2023-03-09 17:33:16
[Usaco2006 Nov]Bad Hair Day 乱发节

Time Limit: 2 Sec  Memory Limit: 64 MB
Submit: 1268  Solved: 625
[Submit][Status][Discuss]

Description

[Usaco2006 Nov]Bad Hair Day 乱发节

Input

* Line 1: 牛的数量 N。

* Lines 2..N+1: 第 i+1 是一个整数,表示第i头牛的高度。

Output

* Line 1: 一个整数表示c[1] 至 c[N]的和。

Sample Input

6
10
3
7
4
12
2

输入解释:

六头牛排成一排,高度依次是 10, 3, 7, 4, 12, 2。

Sample Output

5

3+0+1+0+1=5

HINT

Source

Silver

思路

是不是只有我是二分+st表做的QUQ

对于每头牛,二分它能看到的最远的牛即可;

O(nlogn)

代码实现

 #include<cmath>
#include<cstdio>
const int maxn=8e4+;
inline int min_(int x,int y){return x<y?x:y;}
inline int max_(int x,int y){return x>y?x:y;}
int n,m;
long long ans;
int f[maxn][];
int qj(int l,int r){
int q=log2(r-l+);
return max_(f[l][q],f[r-(<<q)+][q]);
}
int ef(int l,int r){
int now=f[l-][],mid;
while(l<r){
mid=l+r>>;
if(qj(l,mid)>=now) r=mid;
else l=mid+;
}
if(f[l][]>=now) l--;
return l;
}
int main(){
scanf("%d",&n),m=log2(n);
for(int i=;i<=n;i++) scanf("%d",&f[i][]);
for(int j=;j<m;j++)
for(int i=;i<=n;i++)
if(i+(<<j-)>n) f[i][j]=f[i][j-];
else f[i][j]=max_(f[i][j-],f[i+(<<j-)][j-]);
for(int i=;i<n;i++) ans+=ef(i+,n)-i;
printf("%lld\n",ans);
return ;
}