传送门 : COGS 2638. 数列操作ψ 线段树

这道题让我们维护区间最大值,以及维护区间and,or一个数

我们考虑用线段树进行维护,这时候我们就要用到吉司机线段树啦 QAQ

由于发现若干次and,or之后,如果数据分布均匀,那么几乎所有的数在若干次操作后都会变成同一个数

因为我们的and操作中的0位,以及or操作当中的1位,都是可以把整个区间的那一二进制位重置为相同的

我们考虑利用这一个性质

如果我们直接维护一个区间内的值是否是相同的,那么效果会差很多。

我们发现我们在进行and操作的时候只有为0的二进制位才可能更改原本的二进制位

同样的,在进行or操作的时候也只有为1的二进制位才可能更改原本的二进制位

所以我们可以在区间内所有的数的对应的会做出修改的二进制位完全相同时作出区间整体修改

至于区间整体修改,我们很容易发现,实际上就是区间内加上一个数

所以对于每一个线段树节点,维护一个sam值,表示这个线段树代表的区间内二进制位的相同情况

对应二进制位为1,则代表区间内所有值的这一位都是相同的

随后我们通过对区间内所有元素对应二进制位是否相同的情况来判断是否可以进行区间修改即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
inline void read(int &x){
x=0;static char ch;static bool flag;flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
#define rg register int
#define rep(i,a,b) for(rg i=(a);i<=(b);++i)
#define per(i,a,b) for(rg i=(a);i>=(b);++i)
const int maxn = 100010;
const int bas = 0x7fffffff;
int T[maxn<<2],lazy[maxn<<2],sam[maxn<<2];
int a[maxn];
inline void update(int rt){
T[rt] = max(T[rt<<1],T[rt<<1|1]);
sam[rt] = (sam[rt<<1]&sam[rt<<1|1]) & (~(T[rt<<1]^T[rt<<1|1]));
}
inline void pushdown(int rt){
if(lazy[rt] == 0) return ;
T[rt<<1] += lazy[rt];lazy[rt<<1] += lazy[rt];
T[rt<<1|1] += lazy[rt];lazy[rt<<1|1] += lazy[rt];
lazy[rt] = 0;
}
void build(int rt,int l,int r){
if(l == r){
T[rt] = a[l];
sam[rt] = bas;
return ;
}int mid = l+r >> 1;
build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
update(rt);
}
int L,R,val,tmp;
inline bool check_a(int rt){
tmp = (val^bas);
return (tmp & sam[rt]) == tmp;
}
void modify_a(int rt,int l,int r){
if(L <= l && r <= R && check_a(rt)){
tmp = (T[rt] & val) - T[rt];
lazy[rt] += tmp;T[rt] += tmp;
return ;
}int mid = l+r >> 1;pushdown(rt);
if(L <= mid) modify_a(rt<<1,l,mid);
if(R > mid) modify_a(rt<<1|1,mid+1,r);
update(rt);
}
void modify_o(int rt,int l,int r){
if(L <= l && r <= R && (sam[rt] & val) == val){
tmp = (T[rt] | val) - T[rt];
lazy[rt] += tmp;T[rt] += tmp;
return ;
}int mid = l+r >> 1;pushdown(rt);
if(L <= mid) modify_o(rt<<1,l,mid);
if(R > mid) modify_o(rt<<1|1,mid+1,r);
update(rt);
}
int query(int rt,int l,int r){
if(L <= l && r <= R) return T[rt];
int mid = l+r >> 1;pushdown(rt);
if(R <= mid) return query(rt<<1,l,mid);
if(L > mid) return query(rt<<1|1,mid+1,r);
return max(query(rt<<1,l,mid),query(rt<<1|1,mid+1,r));
}
int main(){
//freopen("series_wei.in","r",stdin);
//freopen("series_wei.out","w",stdout);
int n,m;read(n);read(m);
rep(i,1,n) read(a[i]);
build(1,1,n);int opt;
int cnt = 0 ;
while(m--){
read(opt);read(L);read(R);
if(opt == 1) read(val),modify_a(1,1,n);
else if(opt == 2) read(val),modify_o(1,1,n);
else printf("%d\n",query(1,1,n));
}
return 0;
}

COGS 2638. 数列操作ψ 线段树的更多相关文章

  1. 【COGS-2638】数列操作ψ 线段树

    题目链接: http://cogs.pro/cogs/problem/problem.php?pid=2638 Solution 用jry推荐的写法即可做到单次$O(log^{2}N)$,不过随机数据 ...

  2. BZOJ_4636_蒟蒻的数列_线段树+动态开点

    BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将 ...

  3. 【题解】P4247 [清华集训]序列操作(线段树修改DP)

    [题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...

  4. cogs 264. 数列操作 单点修改 区间查询

    http://cogs.pro:8080/cogs/problem/problem.php?pid=pyNimmVeq 264. 数列操作 ★☆   输入文件:shulie.in   输出文件:shu ...

  5. 洛谷P1438 无聊的数列 [zkw线段树]

    题目传送门 无聊的数列 题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]} ...

  6. 【bzoj4636】蒟蒻的数列 离散化+线段树

    原文地址:http://www.cnblogs.com/GXZlegend/p/6801379.html 题目描述 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个 ...

  7. [bzoj4636]蒟蒻的数列_线段树

    蒟蒻的数列 bzoj-4636 题目大意:给定一个序列,初始均为0.n次操作:每次讲一段区间中小于k的数都变成k.操作的最后询问全局和. 注释:$1\le n\le 4\cdot 10^4$. 想法: ...

  8. cogs 1317. 数列操作C 区间修改 区间查询

    1317. 数列操作C ★★★   输入文件:shuliec.in   输出文件:shuliec.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述] 假设有一个长度为 n( ...

  9. cogs 1316. 数列操作B 区间修改 单点查询

    1316. 数列操作B ★★   输入文件:shulieb.in   输出文件:shulieb.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 假设有一个大小为 n(n ...

随机推荐

  1. EFM32JG系列MCU内部温度传感器使用方法

    在很多电子类应用场合中,我们经常需要采集产品工作的周围环境温度,一般采取的方式有两种: 1)外加温度传感器 2)采用MCU内部温度传感器 外加温度传感器会增加产品的成本以及布板空间,所以在很多场合,我 ...

  2. xshell 常用命令

    一.grep 命令 (1)命令格式 grep [选项] pattern [file] (2)常用参数 参数 描述 -c 计算找到 '搜寻字符串'(即 pattern) 的次数 -i 忽略大小写的不同, ...

  3. Qt查找孩子findChild

    转载自[http://blog.csdn.net/liang19890820/article/details/52118210] 简述 在Qt编程过程中,通常会有多个部件嵌套,而大多数部件都有父子依赖 ...

  4. SpringBoot2.0+ElasticSearch网盘搜索实现

    1.ES是如何实现分布式高并发全文检索 2.简单介绍ES分片Shards分片技术 3.为什么ES主分片对应的备分片不在同一台节点存放 4.索引的主分片定义好后为什么不能做修改 5.ES如何实现高可用容 ...

  5. mysql desc esc 基本命令总结

    asc 按升序排列desc 按降序排列 下列语句部分是Mssql语句,不可以在access中使用. SQL分类:DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE)DML—数据操 ...

  6. CNI:容器网络接口

    CNI 简介 不管是 docker 还是 kubernetes,在网络方面目前都没有一个完美的.终极的.普适性的解决方案,不同的用户和企业因为各种原因会使用不同的网络方案.目前存在网络方案 flann ...

  7. Nginx的长链接

    网站使用程序discuz3访问都正常,只有用户登录存在异常,具体就是:用户登陆后会马上显示未登录,然后刷新一下又变成了登录中 这个问题的原因显然是由于session导致,后台有多个web机器,当用户登 ...

  8. Spark- 使用hiveContext时提交作业报错

    在spark上操作hive时不需要搭建hive环境,只需要从现有的hive集群中hive的conf目录下拷贝 hive-site.xml 到spark的conf目录下即可提交程序运行 出现报错 Cau ...

  9. STDIN_FILENO

    1.STDIN_FILENO的作用STDIN_FILENO属于系统API接口库,其声明为 int 型,是一个打开文件句柄,对应的函数主要包括 open/read/write/close 等系统级调用. ...

  10. Prism初研究之使用Prism实现WPF的MVVM模式

    转自:http://www.cnblogs.com/qianzi067/p/5804880.html