前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HDU 6315 Naive Operations(线段树+懒惰标记)

HDU 6315 Naive Operations(线段树+懒惰标记)

作者头像
用户2965768
发布2018-08-30 15:38:39
6930
发布2018-08-30 15:38:39
举报
文章被收录于专栏:wymwymwym

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6315

题意:一行给出n,m,有两个数组,长度为n,其中a数组全为0,b数组接下来一行给你n个数

接着m行是m条命令:

add l r               a数组[l,r]区间的数全都加一

query l r              [l,r] 区间的数  求和,      每个数为a[i]/b[i]

一开始用树状数组做的,TLE了,比赛结束用线段数做的,不懒惰标记依然会TLE

考虑到区间每次加一后,如果求和值不一定会加一,只有当a[i]加了一个b[i]才会加1;

这样每次当a[i]加到一个b[i]时结果加一,用cnt表示结果,laz是加的数,然后cnt++后要让b[i]加上原来的一个b[i]

例如   1 5 2 4 3

对最后一个b[5]而言,a[5]要加3次值才会加一,那么加一之后让b[5]加上原来的一个b[5]变成6,依旧是让a[5]加3次结果加一

#include <bits/stdc++.h> #define N 100005 #define lc (d<<1) #define rc (d<<1|1) #define m (l+r>>1) using namespace std; struct NODE{     int laz,cnt,min,max; }; int b[N]; NODE node[4*N]; int n; void pushUp(int d) {     node[d].min=min(node[lc].min,node[rc].min);     node[d].max=max(node[lc].max,node[rc].max);     node[d].cnt=node[lc].cnt+node[rc].cnt; } void pushDown(int d) {     if(node[d].laz)     {         int v=node[d].laz;         node[d].laz=0;          node[lc].laz+=v;         node[rc].laz+=v;         node[lc].max+=v;         node[rc].max+=v;//由于每次是让b[i]加上自身并不是清零,所以这里也是加v      }  } void build(int l,int r,int d) {     node[d].laz=0;     if(l==r)     {         node[d].cnt=node[d].max=0;         node[d].min=b[l];         return;     }     build(l,m,lc);     build(m+1,r,rc);     pushUp(d); } void updata(int l,int r,int L,int R,int d) {     if(L<=l&&r<=R)     {         node[d].max++;         if(node[d].max<node[d].min)         {             node[d].laz++;             return;         }          if(l==r&&node[d].max>=node[d].min)         {             node[d].cnt++;//结果加一             node[d].min+=b[l];              return;         }     }      pushDown(d);     if(L<=m)         updata(l,m,L,R,lc);     if(R>m)         updata(m+1,r,L,R,rc);     pushUp(d); }

int query(int l,int r,int L,int R,int d) {     if(L<=l&&r<=R)     {         return node[d].cnt;     }     pushDown(d);     int ans=0;     if(L<=m)     ans+=query(l,m,L,R,lc);     if(R>m)     ans+=query(m+1,r,L,R,rc);      return ans; } int main() {     int q;     int x,y;     while(~scanf("%d %d",&n,&q))     {         for(int i=1; i<=n; i++)         {             scanf("%d",&b[i]);         }         build(1,n,1);         char op[6];         int l,r;         while(q--)         {             scanf("%s%d%d",op,&l,&r);             if(op[0]=='a')             {                 updata(1,n,l,r,1);             }             else             {                 printf("%d\n",query(1,n,l,r,1));             }         }     }     return 0; }

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年07月26日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档