[COCI2015-2016#2] VUDU 题解
[COCI2015-2016#2] VUDU 题解
题意
给一个长度为
暴力做法
显然,可以直接枚举区间左端点
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
if(sum[i]-sum[j-1]>=p*(i-j+1)){//乘法避免丢精度
ans++;
}
}
}
用前缀和数组
正解
只要对暴力算法的不等式稍加改变,我们就能得到正解。
对于代码中的不等式,我们可以将不等式转化为:
再结合
对于每一个
时间复杂度为
注意:由于不等式中的左右两项可能很大,所以在操作前需要先对其离散化。
代码
#include<stdio.h>
#include<algorithm>
typedef long long ll;
const ll N=2e6+5;
int n,cnt;
ll p,sum[N],a[N],b[N],g[N],c[N];
int lowbit(int x){return x&~x+1;}
void add(int x,ll v){while(x<=cnt) c[x]+=v,x+=lowbit(x);}
ll query(int x){
ll ans=0;
while(x) ans+=c[x],x-=lowbit(x);
return ans;
}
int main(){
scanf("%d",&n);
ll x;
for(int i=1;i<=n;i++){
scanf("%lld",&x);
sum[i]=sum[i-1]+x;
}
scanf("%lld",&p);
for(int i=1;i<=n;i++){
a[i]=sum[i]-p-p*i;//不等式左边项
b[i]=sum[i-1]-p*i;//不等式右边项
g[++cnt]=a[i],g[++cnt]=b[i];
}
std::sort(g+1,g+cnt+1);//离散化排序
cnt=std::unique(g+1,g+cnt+1)-g-1;//离散化去重
ll ans=0;
for(int i=1;i<=n;i++){
int x=std::lower_bound(g+1,g+cnt+1,a[i])-g;
int y=std::lower_bound(g+1,g+cnt+1,b[i])-g;//离散化
add(y,1);
ans+=query(x);
}
printf("%lld",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App