题解:P11261 [COTS 2018] 直方图 Histogram
what can I say.
三篇题解撤了两篇,怎么说?
但看在没有简单暴力的二阶差分做法下,还是写一篇罢。不懂二阶差分的可以左转 bdfs。
思路
发现
scanf("%d%lld",&n,&p);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
m=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++){
a[i]=lower_bound(b+1,b+1+m,a[i])-b;
while(top&&a[stk[top]]>=a[i])top--;//h[l]<h[i]
L[i]=stk[top];
stk[++top]=i;
}
stk[top=0]=n+1;
for(int i=n;i;i--){
while(top&&a[stk[top]]>a[i])top--;//h[r]<=h[i]
R[i]=stk[top];
stk[++top]=i;
if(a[R[i]]!=a[i]){//当h[r]=h[i]直接不算
/*计算答案*/
}
}
那么知道
if(a[R[i]]!=a[i]){
int len=R[i]-1-L[i];
long long l=max(1ll,p/b[a[i]]+(p%b[a[i]]!=0)),r=(!max(b[a[L[i]]],b[a[R[i]]])?len:min(1ll*len,p/max(b[a[L[i]]],b[a[R[i]]])-(p%max(b[a[L[i]]],b[a[R[i]]])==0)));
if(l<=r){
c[l]+=(__int128)(len-l+1)*b[a[i]];
c[l+1]+=(__int128)(-1-(len-l+1))*b[a[i]];
c[r+1]+=(__int128)(1-(len-r+1))*b[a[i]];
c[r+2]+=(__int128)(len-r+1)*b[a[i]];
d[l]+=len-l+1;
d[l+1]+=-1-(len-l+1);
d[r+1]+=1-(len-r+1);
d[r+2]+=len-r+1;
}
if(++r<=len){
int x=b[a[i]]-max(b[a[L[i]]],b[a[R[i]]]);
c[r]+=(__int128)(len-r+1)*x;
c[r+1]+=(__int128)(-1-(len-r+1))*x;
c[len+2]+=x;
}
}
然后就没了,注意可能会爆 long long。附上结尾部分的代码:
for(int i=1;i<=n;i++){
c[i]+=c[i-1];
d[i]+=d[i-1];
}
for(int i=1;i<=n;i++){
c[i]+=c[i-1];
d[i]+=d[i-1];
long long h=p/i+(p%i!=0);
ans+=c[i]-d[i]*(h-1);
}
print(ans);