COGS 2638. 数列操作ψ 线段树
传送门 : 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. 数列操作ψ 线段树的更多相关文章
- 【COGS-2638】数列操作ψ 线段树
题目链接: http://cogs.pro/cogs/problem/problem.php?pid=2638 Solution 用jry推荐的写法即可做到单次$O(log^{2}N)$,不过随机数据 ...
- BZOJ_4636_蒟蒻的数列_线段树+动态开点
BZOJ_4636_蒟蒻的数列_线段树+动态开点 Description 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个数列,初始值均为0,他进行N次操作,每次将 ...
- 【题解】P4247 [清华集训]序列操作(线段树修改DP)
[题解]P4247 [清华集训]序列操作(线段树修改DP) 一道神仙数据结构(DP)题. 题目大意 给定你一个序列,会区间加和区间变相反数,要你支持查询一段区间内任意选择\(c\)个数乘起来的和.对1 ...
- cogs 264. 数列操作 单点修改 区间查询
http://cogs.pro:8080/cogs/problem/problem.php?pid=pyNimmVeq 264. 数列操作 ★☆ 输入文件:shulie.in 输出文件:shu ...
- 洛谷P1438 无聊的数列 [zkw线段树]
题目传送门 无聊的数列 题目背景 无聊的YYB总喜欢搞出一些正常人无法搞出的东西.有一天,无聊的YYB想出了一道无聊的题:无聊的数列...(K峰:这题不是傻X题吗) 题目描述 维护一个数列{a[i]} ...
- 【bzoj4636】蒟蒻的数列 离散化+线段树
原文地址:http://www.cnblogs.com/GXZlegend/p/6801379.html 题目描述 蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列 题目描述 DCrusher有一个 ...
- [bzoj4636]蒟蒻的数列_线段树
蒟蒻的数列 bzoj-4636 题目大意:给定一个序列,初始均为0.n次操作:每次讲一段区间中小于k的数都变成k.操作的最后询问全局和. 注释:$1\le n\le 4\cdot 10^4$. 想法: ...
- cogs 1317. 数列操作C 区间修改 区间查询
1317. 数列操作C ★★★ 输入文件:shuliec.in 输出文件:shuliec.out 简单对比时间限制:1 s 内存限制:128 MB [题目描述] 假设有一个长度为 n( ...
- cogs 1316. 数列操作B 区间修改 单点查询
1316. 数列操作B ★★ 输入文件:shulieb.in 输出文件:shulieb.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] 假设有一个大小为 n(n ...
随机推荐
- CF932E Team Work(第二类斯特林数)
题目 CF932E Team Work 前置:斯特林数\(\Longrightarrow\)点这里 做法 \[\begin{aligned}\\ &\sum\limits_{i=1}^n C_ ...
- 20145201《Java程序设计》第九周学习总结
20145201 <Java程序设计>第九周学习总结 教材学习内容总结 JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行操作,开发人员无须接触底层 ...
- 0927-转载:SSM:spring+springmvc+mybatis框架中的XML配置文件功能详细解释
这篇文章暂时只对框架中所要用到的配置文件进行解释说明,而且是针对注解形式的,框架运转的具体流程过两天再进行总结. spring+springmvc+mybatis框架中用到了三个XML配置文件:web ...
- C++二阶构造函数
转自:http://blog.51cto.com/9291927/1896411 一.构造函数的问题 构造函数存在问题: A.构造函数只提供自动初始化成员变量的机会 B.不能保证初始化逻辑一定成功,如 ...
- 解析Linux系统的平均负载概念
一.什么是系统平均负载(Load average)? 在Linux系统中,uptime.w.top等命令都会有系统平均负载load average的输出,那么什么是系统平均负载呢?系统平均负载被定义为 ...
- ActiveMQ JMS实现消息发送
一.创建配置消息发送接收目的地. ActiveMQ中间件地址 JMS_BROKER_URL=failover://(tcp://192.168.1.231:61616) QUEUE_BUSP_TP_S ...
- springBean的作用域
Bean的作用域有五个类别 1.singleton,不写的话默认也是这个,这个的意思就是,单例的,就是说,不管你new多少次,都是一个对象 2.prototype,就是说每次new一个bean都是一个 ...
- DEV控件的Gridview小技巧总结
1.设置Gridview控件的某列不可编辑 this.gridData.gridView1.Columns["change_date"].OptionsColumn.AllowEd ...
- java 判断对象的所有属性是否为空解决方案
public static boolean allfieldIsNUll(Object o){ try{ for(Field field:o.getClass().getDeclaredFields( ...
- scala学习手记32 - trait选择性混入
继续上一节. 狗当然是人类的好朋友.但是藏獒呢?这玩意儿又蠢又笨又凶狠,肯定不能算很多人的好朋友了.其实,刚才那句话还可以修正一下下:我们接受的狗才是我们的好朋友. 用程序怎么实现呢?在java里面, ...