题意:数量为N的序列a和b,a初始全为0,b为给定的1-N的排列。有两种操作:1.将a序列区间[L,R]中的数全部+1;2.查询区间[L,R]中的 ∑⌊ai/bi⌋(向下取整)

分析:对于一个位置i,如果ai<bi,那么该位置不能对结果做出贡献;而当某一次操作后,ai>=bi了,就对结果的贡献值+1。那么可以用在线段树的结点中维护每个区间的最大a和最小b,和已经产生的贡献cnt。如果一个区间中最大的a超过了b,那么就说明此次更新操作使该区间的结果产生了变化,那么就要向下找到那个产生贡献的位置。当更新完结果值以后,就将这个位置上的bi再加上bi(由于结果要求向下取整),那么相当于这个位置的ai又要重新更新bi次才能再次产生贡献。

所以,update函数中,如果出现a>=b的情况,那么我们必须递归到最底层找到出现;如果a<b,那么只要打上延迟标记即可。

#include<bits/stdc++.h>
#define Lson rt<<1,l,m
#define Rson rt<<1|1,m+1,r
using namespace std;
typedef long long LL;
const int maxn =1e5+;
struct Node{
int cnt,addv,maxa,minb;
}tree[maxn<<];
int b[maxn];
void pushup(int rt)
{
tree[rt].cnt = tree[rt<<].cnt+tree[rt<<|].cnt;
tree[rt].maxa = max(tree[rt<<].maxa,tree[rt<<|].maxa);
tree[rt].minb = min(tree[rt<<].minb,tree[rt<<|].minb);
}
void pushdown(int rt)
{
if(tree[rt].addv){
int v=tree[rt].addv;
tree[rt].addv=;
tree[rt<<].maxa+=v;
tree[rt<<|].maxa+=v;
tree[rt<<].addv+=v;
tree[rt<<|].addv+=v;
}
}
void build(int rt,int l,int r)
{
tree[rt].addv=;
if(l==r){
tree[rt].cnt = tree[rt].maxa = ;
tree[rt].minb = b[l];
return;
}
int m = (l+r)>>;
build(Lson);
build(Rson);
pushup(rt);
}
void update(int rt,int l,int r,int L,int R)
{
if(L<=l && R>=r){
tree[rt].maxa++;
if(tree[rt].maxa<tree[rt].minb){ //还没有元素做出贡献
tree[rt].addv++;
return;
}
else if(l==r){
tree[rt].cnt++;
tree[rt].minb+=b[l];
return;
}
}
pushdown(rt);
int m = (l+r)>>;
if(L<=m)update(Lson,L,R);
if(R>m)update(Rson,L,R);
pushup(rt);
} int query(int rt,int l,int r,int L,int R)
{
if(L<=l&&R>=r) return tree[rt].cnt;
int m =(l+r)>>;
pushdown(rt);
int ans=;
if(L<=m) ans+=query(Lson,L,R);
if(R>m) ans+=query(Rson,L,R);
return ans;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T,N,M,u,v,tmp;
while(scanf("%d%d",&N,&M)==){
for(int i=;i<=N;++i) scanf("%d",&b[i]);
build(,,N);
char op[];
int L,R;
while(M--){
scanf("%s %d %d",op,&L,&R);
if(op[]=='a') update(,,N,L,R);
else printf("%d\n",query(,,N,L,R));
}
}
return ;
}

最新文章

  1. .net erp(办公oa)开发平台架构概要说明之表单设计器
  2. RabbitMQ入门教程——.NET客户端使用
  3. SQL中如何检查死锁
  4. 全7 天玩转 ASP.NET MVC — 第 2 天
  5. Web服务器与Servlet容器
  6. Linux下tcp协议socket的recv函数返回时机分析(粘包)
  7. Ubuntu 截屏
  8. css模块化思想(一)--------命名是个技术活
  9. PHP之curl
  10. 【转】科普Spark,Spark是什么,如何使用Spark
  11. 【python之旅】python简介和入门
  12. cmake 手册系列
  13. gsoap:实现线程池处理时获取到客户端的ip
  14. 关于php的命名空间
  15. sqlalchemy 使用
  16. Python学习笔记【Nginx】:Nginx使用与完全卸载
  17. golang 框架 之 CHI
  18. virtualbox装个 ubuntu
  19. Linux root密码忘记了怎么办?
  20. 写在开始前---ajax中的会话过期与重新登录

热门文章

  1. 第一百三十八节,JavaScript,封装库--插件
  2. java小数位-DecimalFormat(转)
  3. mui 子页面切换父页面底部导航
  4. NLM算法
  5. 【转】VC++计算当前时间点间隔N天的时间(不使用CTimeSpan类)
  6. 虚拟机安装Ubuntu过程记录
  7. poj 3422(最小费用最大流)
  8. sublime text 3 并列显示
  9. iOS 计算某个月的天数 计算某天的星期
  10. 第一份PHP程序