很不错的一道题

给你一个长度为n的数组,问共有多少个区间满足区间之和小于给定的数t

这种题一般做法肯定是枚举,固定左端点枚举右端点,枚举的过程需要优化,否则就是n方

这道题我先求一个前缀和,然后逆着枚举,显然问题转化为了对于一个数,如果寻找他右边的数哪些小于它+t,这就转化为了区间求和,可以树状数组或者线段树,但是数的范围太大,因此需要用离散化

这道题的还有一个问题是定位,有一个很简单的定位方法就是把每一个前缀和+t也放进去,这样去定位就很简单了

另外就是使用upper_bound不过找的数要减一

具体做法看代码

#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
#define pf printf
#define int long long
#define IO ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int maxn=+;
int sum[maxn],a[maxn],up;
vector<int> v;
int n,t;
inline int lowbit(int x){return x&-x;}
void add(int x,int d)
{
while(x<=up){
sum[x]+=d;x+=lowbit(x);
}
}
int Sum(int x)
{
int ret=;
while(x>){
ret+=sum[x];
x-=lowbit(x);
}
return ret;
}
main()
{
IO;
int ans=;
cin>>n>>t;
for(int i=;i<=n;i++){
cin>>a[i];
a[i]+=a[i-];
v.push_back(a[i]);
if(a[i]<t) ans++;
}
sort(v.begin(),v.end());
v.erase(unique(v.begin(),v.end()),v.end());
up=v.size();
for(int i=n;i;i--){
ans+=Sum(upper_bound(v.begin(),v.end(),a[i]+t-)-v.begin());
add(lower_bound(v.begin(),v.end(),a[i])-v.begin()+,);
}
cout<<ans<<endl;
}

最新文章

  1. Full Gc经历分析
  2. HBase Shell操作
  3. iOS远程推送1
  4. coding
  5. 2821: 作诗(Poetize)
  6. 如何在web.xml文件中引入其他的xml文件(拆分web.xml)
  7. 前后端交互实现(nginx,json,以及datatable的问题相关)
  8. vue组件创建学习总结
  9. Cocos Creator 动态设置Canvas的宽度与高度,更改适配
  10. lodash 判断一个数据是否包含另一个数组
  11. 快速制作U盘启动盘和U盘安装盘的方法
  12. IdentityServer4 中文文档 -11- (快速入门)添加基于 OpenID Connect 的用户认证
  13. C#-MVC开发微信应用(2)--微信消息的处理和应答
  14. 大白dmeo (转的)
  15. Scrum 项目准备4.0
  16. 【轮廓线DP】POJ2411-Mondriaan&#39;s Dream
  17. 跟着百度学PHP[8]-setcookie的其他参数学习
  18. .NET System.Web.HttpContext.Current.Request报索引超出数组界限。
  19. PL/SQL那点事--&gt;修改Oracle数据库里面的字段长度
  20. HDU 3669 Cross the Wall(斜率DP+预处理)

热门文章

  1. 安装ik分词插件
  2. 渡一教育公开课重点笔记之css
  3. C#开源组件DocX处理Word文档基本操作(二)
  4. lwip的netif状态管理
  5. Effective Java, Third Edition
  6. 获取本机网卡ip地址
  7. Day17-18前端学习之路——Javascript事件
  8. cornerstone使用beyond compare比较工具
  9. [dubbo 源码之 ]1. 服务提供方如何发布服务
  10. Shiro -- (三) 自定义Realm