题解:P11261 [COTS 2018] 直方图 Histogram
考虑到确定了
假设当前点左子树大小为
考虑枚举
根据数论知识注意到满足
总时间复杂度
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e5+114;
int stk[maxn],tp;
int n,h[maxn],p;
int ls[maxn],rs[maxn];
int pre[maxn];
int calc(int l,int r,int c){
c++;
l=max(l,(p+c-1)/c);
if(l<=r) return c*(r-l+1)-pre[r]+pre[l-1];
else return 0;
}
int ans;
void solve(int cur,int l,int r){
if(cur==0) return ;
solve(ls[cur],l,cur-1);
solve(rs[cur],cur+1,r);
int L=cur-l+1,R=r-cur+1;
if(L>R) swap(L,R);
for(int i=1;i<=L;i++) ans+=calc(i,i+R-1,h[cur]);
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>p;
for(int i=1;i<=n;i++) pre[i]=pre[i-1]+(p+i-1)/i;
for(int i=1;i<=n;i++){
cin>>h[i];
int k=tp;
while(k>0&&h[stk[k]]>h[i]) k--;
if(k!=0) rs[stk[k]]=i;
if(k<tp) ls[i]=stk[k+1];
tp=k;
stk[++tp]=i;
}
solve(stk[1],1,n);
cout<<ans<<'\n';
return 0;
}