RMQ(或运算)

RMQ

https://ac.nowcoder.com/acm/contest/283/J

题目描述

按位或运算:处理两个长度相同的二进制数,两个相应的二进位中只要有一个为1,该位的结果值为1。例如5 or 3 = 7

        0101(十进制5)
     OR 0011(十进制3)
      = 0111(十进制7)
—— 引用自 位运算——维基百科
小姐姐想要一种数据结构,支持如下操作:
对于一个整数数组:    
1. 给定L和R,输出[L,R]中元素的和
2. 给定L,R和X,将[L,R]中每个元素与X进行按位或运算
3. 数组索引从1开始
按位或在C\C++、Java、Python中为'|'运算符

输入描述:

第一行为两个整数 n 和 m,表示数组元素个数和操作的次数
第二行有n个整数,第i个表示数组array中第i个元素的值array[i]
接下来m行,每行只有两种可能:
1. SUM L R
表示对[L,R]的元素求和并输出
2. OR L R X
表示对[L,R]的每一个元素与X进行按位或运算,L、R为base 1的数字序号
数据满足:
 

输出描述:

对于每个SUM操作,在一行内输出该操作的结果。
示例1

输入

5 3
1 2 3 4 5
SUM 1 4
OR 2 5 10
SUM 1 4

输出

10
36

说明

在第一个SUM操作时数组a为[1, 2, 3, 4, 5],因此[1,4]和为10

在第二个SUM操作时数组a为[1, 10, 11, 14, 15],因此[1,4]和为36



 1 #include<bits/stdc++.h>
 2 #define maxn 200005
 3 #define lson l,mid,rt<<1
 4 #define rson mid+1,r,rt<<1|1
 5 typedef long long ll;
 6 using namespace std;
 7 ll tree[maxn<<3],lazy[maxn<<3];
 8 
 9 int n,m;
10 
11 void push_up(int rt){
12     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
13     lazy[rt]=lazy[rt<<1]|lazy[rt<<1|1];
14 }
15 
16 
17 void build(int l,int r,int rt){
18     if(l==r){
19         cin>>tree[rt];
20         lazy[rt]=~tree[rt];
21         return;
22     }
23     int mid=(l+r)/2;
24     build(lson);
25     build(rson);
26     push_up(rt);
27 }
28 
29 ll query(int L,int R,int l,int r,int rt){
30     if(L<=l&&R>=r){
31         return tree[rt];
32     }
33     ll ans=0;
34     int mid=(l+r)/2;
35     if(L<=mid) ans+=query(L,R,lson);
36     if(R>mid) ans+=query(L,R,rson);
37     push_up(rt);
38     return ans;
39 }
40 
41 void add(int L,int R,int v,int l,int r,int rt){
42     if(l==r){
43         tree[rt]+=lazy[rt]&v;
44         lazy[rt]-=lazy[rt]&v;
45         return;
46     }
47     int mid=(l+r)/2;
48     if(!(lazy[rt]&v)) return;
49     if(L<=mid) add(L,R,v,lson);
50     if(R>mid) add(L,R,v,rson);
51     push_up(rt);
52 
53 }
54 
55 int main(){
56     std::ios::sync_with_stdio(false);
57     cin>>n>>m;
58     build(1,n,1);
59     string str;
60     int x,y,v;
61     while(m--){
62         cin>>str>>x>>y;
63         if(x>y) swap(x,y);
64         if(str=="SUM"){
65             cout<<query(x,y,1,n,1)<<endl;
66         }
67         else{
68             cin>>v;
69             add(x,y,v,1,n,1);
70         }
71     }
72 
73 }
View Code

 

posted on 2018-11-27 13:17  Fighting_sh  阅读(341)  评论(0编辑  收藏  举报

导航