1004 Counting Stars

题意:

  • 给出一个长为n的序列(1e5),支持3种操作:
    1:查询[l,r]的区间和
    2:修改[l,r]中每个数,都减去lowbit(x)
    3:修改[l,r]中每个数,都加上2^k, 2^k<=ai

思路:

  • 对于操作2,减去lowbit(x)相当于去掉最后一位的1。可以发现,不断删1后,一个数最多删32次就会变为0,此后修改查询都是0。所以我们可以打个tag表示该区间是否所有数为0,用标记下传维护,剩余的情况暴力修改。
  • 对于操作3,加上2^k相当于第一位1左移一位。可以发现,该操作仅与最高位有关,与后面的位无关。所以我们可以把最高位单独维护,操作3相当于整个区间乘2,线段树维护区间乘法即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5+10;
const LL mod = 998244353;LL a1[maxn], a2[maxn];
LL lowbit(LL x){ return x&(-x);}//线段树:s1维护最高位, s2维护剩余位,tg1表示区间乘2,tg2表示区间全为0。
LL s1[maxn<<2], s2[maxn<<2], tg1[maxn<<2], tg2[maxn<<2];
#define lch p<<1
#define rch p<<1|1
void pushup(int p){   //更新完pushups1[p] = (s1[lch]+s1[rch])%mod;   //维护区间和s2[p] = (s2[lch]+s2[rch])%mod;  //维护区间和tg2[p] = tg2[lch]&tg2[rch];        //左右子树都全为0了才为0
}
void pushdown(int p){ //查询前pushdowntg1[lch] = tg1[lch]*tg1[p]%mod;tg1[rch] = tg1[rch]*tg1[p]%mod;s1[lch] = s1[lch]*tg1[p]%mod;s1[rch] = s1[rch]*tg1[p]%mod;tg1[p] = 1;tg2[lch] |= tg2[p];tg2[rch] |= tg2[p];if(tg2[lch])s2[lch] = 0;if(tg2[rch])s2[rch] = 0;
}
void build(int p, int l, int r){tg1[p] = 1, tg2[p] = 0;        //区间乘标记1,全为0标记0。if(l == r){s1[p] = a1[l], s2[p] = a2[l];return ;}int mid = l+r>>1;build(lch, l, mid);build(rch, mid+1, r);pushup(p);
}
LL query(int p, int l, int r, int ll, int rr){//return sum{s1+s2}[ll,rr];if(ll>r || rr<l)return 0;if(ll<=l && r<=rr){return (s1[p]+s2[p])%mod;}pushdown(p);int mid = l+r>>1;LL ans = 0;ans += query(lch, l, mid, ll, rr);ans += query(rch, mid+1, r, ll, rr);ans %=mod;return ans;
}
void update1(int p, int l, int r, int ll, int rr){//s2[ll,rr]-=lowbit;(暴力)if(ll>r || rr<l)return ;//区间在范围外if(tg2[p])return ;     //区间全为0,再见if(l==r){                //到叶节点才能单点暴力修改if(s2[p]!=0){ s2[p]-=lowbit(s2[p]);}//去掉一个lowbitelse {s1[p]=0; tg2[p]=1;}//除了最高位已经都是0了,那最高位没了return ;}pushdown(p);int mid = l+r>>1;update1(lch, l, mid, ll, rr);update1(rch, mid+1, r, ll, rr);pushup(p);
}
void update2(int p, int l, int r, int ll, int rr){//s1[ll,rr] *= 2;(Lazy)if(ll>r || rr<l)return ;   //区间完全在范围外if(ll<=l && r<=rr){           //区间完全被包含s1[p] = s1[p]*2%mod;   //sum[l,r] *= 2;tg1[p] = tg1[p]*2%mod; //lazy tag, then return ;return ;}pushdown(p);int mid = l+r>>1;update2(lch, l, mid, ll, rr);update2(rch, mid+1, r, ll, rr);pushup(p);
}int main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int T;  cin>>T;while(T--){int n;  cin>>n;for(int i = 1; i <= n; i++){LL x;  cin>>x;for(int k=30; k>=0; k--){if((1ll<<k)<=x){ //找到最高位a1[i] = 1ll<<k; //提取最高位a2[i] = x-a1[i];//存剩余的数break; }}}build(1,1,n);int q;  cin>>q;for(int i = 1; i <= q; i++){int op, l, r;  cin>>op>>l>>r;if(op==1)cout<<query(1,1,n,l,r)<<"\n";else if(op==2)update1(1,1,n,l,r);else update2(1,1,n,l,r);}}return 0;
}

【HDOJ7059】Counting Stars(线段树,区间加,乘,标记)相关推荐

  1. 线段树 区间加 gcd 差分

    小阳的贝壳 如果线段树要维护区间gcd 这个很简单,但是如果有了区间加,维护gcd 就比较麻烦了. 这个首先可以证明的是 gcd(x,y,z)=gcd(x,y-x,z-y)   这个可以推到 n 个 ...

  2. 2021HDU多校8 - 7059 Counting Stars(线段树)

    题目链接:点击查看 题目大意:给出 nnn 个数字,需要执行 mmm 次操作,每次操作分为下列三种类型: 1 l r :输出区间 [l,r][l,r][l,r] 的 sumsumsum 和 2 l r ...

  3. 洛谷 P3368 【模板】树状数组 2(线段树区间加单点查找)

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的值 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. 第二行包含N个 ...

  4. 扶桑号战列舰 (单调栈+线段树区间更新懒惰标记 or 栈)

    传送门 •题目描述 题目描述 众所周知,一战过后,在世界列强建造超无畏级战列舰的竞争之中,旧日本海军根据"个舰优越主义",建造了扶桑级战列舰,完工时为当时世界上武装最为强大的舰只. ...

  5. poj 2352 Stars 线段树(先建后查/边建边查)/树状数组三种方法思路详解,带你深入了解线段树难度⭐⭐⭐★

    poj 2352 Stars 目录 poj 2352 Stars 1.树状数组 2.线段树,先建树后查找 3.线段树,边建树边查找 Description Astronomers often exam ...

  6. codevs 1082 线段树区间求和

    codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...

  7. POJ 2352 Stars (线段树)

    POJ 2352 Stars (线段树) 手动博客搬家:本文发表于20170819 22:11:49, 原地址https://blog.csdn.net/suncongbo/article/detai ...

  8. 2021牛客暑期多校训练营7 xay loves monotonicity 线段树区间合并

    传送门 文章目录 题意: 思路: 题意: 题面挺绕口的,还是看原题比较好. 大概的意思就是让你从给定的区间中选择一个以左端点为起点的一个上升子序列,让后将这些下标存下来,在bbb中将这些位置拿出来后, ...

  9. 【地狱副本】数据结构之线段树Ⅲ——区间最值/赋值/修改/历史值操作(HDU5306,Tyvj 1518,【清华集训2015】V,HDU6315,HDU1828,POJ3162)

    文章目录 Gorgeous Sequence Tyvj 1518 CPU监控 [清华集训2015]V Naive Operations Picture Walking Race Gorgeous Se ...

  10. 【bzoj4355】Play with sequence 线段树区间最值操作

    题目描述 维护一个长度为N的序列a,现在有三种操作: 1)给出参数U,V,C,将a[U],a[U+1],...,a[V-1],a[V]都赋值为C. 2)给出参数U,V,C,对于区间[U,V]里的每个数 ...

最新文章

  1. tinypdf虚拟打印机中文版
  2. CG CTF WEB /x00
  3. Java反射机制概念及应用场景
  4. php生成图片文件流,php如何将base64数据流文件转换为图片文件?
  5. SpringBoot 2 整合 Spring Session 最简操作
  6. HDU4025 Equation of XOR [二分+状态压缩]
  7. [转载]数字全息与计算全息
  8. HTML5期末大作业:运动系列——NBA篮球主题学生网页设计(7个页面) HTML+CSS+JavaScript 体育网页设计HTML代码 学生网页课程设计期末作业下载 大学生网页设计制作成...
  9. 教学网站毕业设计源码【演示视频】
  10. PMBOK第六版学习笔记
  11. 2018网易互娱笔试题-手势锁
  12. 轻量级Qt键盘-介绍篇
  13. antd select 可搜索值
  14. vue项目设置footer始终处于页面底部
  15. 请假代码java web_学生请假管理系统
  16. OpenGL画自行车+菜单设置(附源码)
  17. 传统系统架构与中台架构的区别和联系
  18. c语言数组读心术,超准,一棵树的读心术
  19. 精密划片机:半导体材料在芯片生产制造过程中的关键性作用
  20. iMeta | 调控肠道菌群的宿主源代谢分子概述

热门文章

  1. goto 语句和标号
  2. 使用 IDEA 创建 Scala 工程
  3. 布尔操作的“骤死式”(short-circuiting behavior)
  4. ibm v7000配置文档_IBM_V7000底层结构及服务器数据恢复案例详解
  5. 美国python网课免费-去不了USA?那又怎样?美国名校网课免费学!
  6. python练手经典100例-10 个最值得 Python 新人练手的有趣项目
  7. python画50个图-python绘制多个子图的实例
  8. 云原生游戏《云联物语》揭开神秘面纱 云鹭科技温向东带你深度了解云原生游戏领域...
  9. 语音识别概念午后大跌 语音识别概念股一览表
  10. 计数译码显示电路实验报告总结_译码器及其应用