[ARC075E] Meaningful Mean
[ARC075E] Meaningful Mean
好题。
首先显然有一个暴力做法,也就是 的,考虑暴力枚举每一个区间,查询区间和显然可以考虑预处理前缀和。判断一下这个和是否大于等于 即可。
核心的一行是:
if(s[i]-s[j-1]>=k*(i-j+1))
然后考虑把这个式子拆开。
显然我们可以预处理 的所有 ,所以就变成了在 中找小于等于 的值。显然可以用一个树状数组去维护,类似于求逆序对,开一个值域大小的树状数组,按照逆序对的求法来就好了。
注意,当 时, 为 ,在 的预处理中是处理不到的,所以我们要把第一个位置留出来给 ,后面整体挪一个位置即可。
#include<bits/stdc++.h>
using namespace std;
const int N =1e6+10;
#define int long long
int n,k;
struct node
{
int val,num;
}a[N];
bool cmp(node a,node b)
{
if(a.val==b.val)
return a.num<b.num;
return a.val<b.val;
}
int ranks[N],c[N],s[N];
int lowbit(int x)
{
return x&-x;
}
void update(int x,int change)
{
for(int i=x;i<=n+1;i+=lowbit(i))
c[i]+=change;
}
int Query(int x)
{
int sum=0;
for(int i=x;i>0;i-=lowbit(i))
sum+=c[i];
return sum;
}
signed main()
{
cin>>n>>k;
for(int i=1,x;i<=n;i++)
cin>>x,s[i]=s[i-1]+x;
a[1].val=0,a[1].num=1;
for(int i=2;i<=n+1;i++)
a[i].val=s[i-1]-k*(i-1),a[i].num=i;
sort(a+1,a+n+2,cmp);
for(int i=0;i<=n+1;i++)
ranks[a[i].num]=i;
int ans=0;
for(int i=1;i<=n+1;i++)
ans+=Query(ranks[i]),update(ranks[i],1);
cout<<ans<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现