Problem 2105 Digits Count

 Problem Description

Given N integers A={A[0],A[1],...,A[N-1]}. Here we have some operations:

Operation 1: AND opn L R

Here opn, L and R are integers.

For L≤i≤R, we do A[i]=A[i] AND opn (here "AND" is bitwise operation).

Operation 2: OR opn L R

Here opn, L and R are integers.

For L≤i≤R, we do A[i]=A[i] OR opn (here "OR" is bitwise operation).

Operation 3: XOR opn L R

Here opn, L and R are integers.

For L≤i≤R, we do A[i]=A[i] XOR opn (here "XOR" is bitwise operation).

Operation 4: SUM L R

We want to know the result of A[L]+A[L+1]+...+A[R].

Now can you solve this easy problem?

 Input

The first line of the input contains an integer T, indicating the number of test cases. (T≤100)

Then T cases, for any case, the first line has two integers n and m (1≤n≤1,000,000, 1≤m≤100,000), indicating the number of elements in A and the number of operations.

Then one line follows n integers A[0], A[1], ..., A[n-1] (0≤A[i]<16,0≤i<n).

Then m lines, each line must be one of the 4 operations above. (0≤opn≤15)

 Output

For each test case and for each "SUM" operation, please output the result with a single line.

 Sample Input

1 4 4 1 2 4 7 SUM 0 2 XOR 5 0 0 OR 6 0 3 SUM 0 2

 Sample Output

7 18

题意不多说了。 观察下a的值表示成二进制不会超过4位内存刚刚够。对每一位维护一下线段树就好了。

具体维护方法如下:

由于  :   1 & 0 = 0

0 & 0 =0    所以&0会改变区间值。

1& 1 =1

0&1=0  所以&1 区间值不变,可以忽略。

同理可以分析其他的操作。然后线段树lazy维护一下1的个数就好了。  注意xor 和& or是互斥的,也就是说当标记了&或or时应把标记 xor清空。

  1 // by cao ni ma
  2 // hehe
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <vector>
  7 #include <queue>
  8 using namespace std;
  9 const int MAX = +;
 10 typedef long long ll;
 11 int sum[][MAX<<];
 12 int col_or[][MAX<<],col_xor[][MAX<<];
 13 int A[MAX];
 14 void pushup(int o,int cur){
 15     sum[cur][o]=sum[cur][o<<]+sum[cur][o<<|];
 16 }
 17 
 18 void pushdown(int o,int cur,int m){
 19     if(col_or[cur][o]!=-){
 20         col_xor[cur][o<<]=col_xor[cur][o<<|]=;
 21         col_or[cur][o<<]=col_or[cur][o<<|]=col_or[cur][o];
 22         sum[cur][o<<]=(m-(m>>))*col_or[cur][o<<];
 23         sum[cur][o<<|]=(m>>)*col_or[cur][o<<|];
 24         col_or[cur][o]=-;
 25     }
 26     if(col_xor[cur][o]){
 27         col_xor[cur][o<<]^=,col_xor[cur][o<<|]^=;
 28         sum[cur][o<<]=((m-(m>>))-sum[cur][o<<]);
 29         sum[cur][o<<|]=((m>>)-sum[cur][o<<|]);
 30         col_xor[cur][o]=;
 31     }
 32 }
 33 
 34 void build(int L,int R,int o,int cur){
 35     col_or[cur][o]=-;
 36     col_xor[cur][o]=;
 37     if(L==R){
 38         sum[cur][o]=((A[L]&(<<cur))?:);
 39     }
 40     else{
 41         int mid=(L+R)>>;
 42         build(L,mid,o<<,cur);
 43         build(mid+,R,o<<|,cur);
 44         pushup(o,cur);
 45     }
 46 }
 47 
 48 void modify2(int L,int R,int o,int ls,int rs,int v,int cur){
 49     if(ls<=L && rs>=R){
 50         col_xor[cur][o]=;
 51         col_or[cur][o]=v;
 52         sum[cur][o]=v*(R-L+);
 53         return ;
 54     }
 55     pushdown(o,cur,R-L+);
 56     int mid=(R+L)>>;
 57     if(ls<=mid) modify2(L,mid,o<<,ls,rs,v,cur);
 58     if(rs>mid) modify2(mid+,R,o<<|,ls,rs,v,cur);
 59     pushup(o,cur);
 60 
 61 }
 62 
 63 void modify1(int L,int R,int o,int ls,int rs,int v,int cur){
 64     if(ls<=L && rs>=R){
 65         if(col_or[cur][o]!=-){
 66             col_or[cur][o]^=;
 67             sum[cur][o]=(R-L+)-sum[cur][o];
 68             return ;
 69         }
 70         else{
 71             col_xor[cur][o]^=;
 72             sum[cur][o]=(R-L+)-sum[cur][o];
 73             return ;
 74         }
 75     }
 76     pushdown(o,cur,R-L+);
 77     int mid=(R+L)>>;
 78     if(ls<=mid) modify1(L,mid,o<<,ls,rs,v,cur);
 79     if(rs>mid) modify1(mid+,R,o<<|,ls,rs,v,cur);
 80     pushup(o,cur);
 81 }
 82 
 83 int Query(int L,int R,int o,int ls,int rs,int cur) {
 84     if(ls<=L && rs>=R) return sum[cur][o];
 85     pushdown(o,cur,R-L+);
 86     int mid=(R+L)>>; int ans=;
 87     if(ls<=mid) ans+=Query(L,mid,o<<,ls,rs,cur);
 88     if(rs>mid) ans+=Query(mid+,R,o<<|,ls,rs,cur);
 89     return ans;
 90 }
 91 
 92 int main(){
 93     int n,m,cas,ls,rs,val;
 94     char op[];
 95     scanf("%d",&cas);
 96     while(cas--){
 97         scanf("%d %d",&n,&m);
 98         for(int i=;i<=n;i++) {
 99             scanf("%d",&A[i]);
         }
         for(int i=;i<;i++) {
             build(,n,,i);
         }
         for(int i=;i<m;i++) {
             scanf("%s",op);
             if(op[]=='S'){
                 scanf("%d %d",&ls,&rs);
                 ls++,rs++;
                 int ans=;
                 for(int i=;i<;i++) {
                     ans+=Query(,n,,ls,rs,i)*(<<i);
                 }
                 printf("%d\n",ans);
             }
             else if(op[]=='O'){
                 scanf("%d %d %d",&val,&ls,&rs);
                 rs++,ls++;
                 for(int i=;i<;i++) {
                     if(val&(<<i)){
                         modify2(,n,,ls,rs,,i);
                     }
                 }
             }
             else if(op[]=='A'){
                 scanf("%d %d %d",&val,&ls,&rs);
                 rs++,ls++;
                 for(int i=;i<;i++) {
                     if(!(val&(<<i))){
                        modify2(,n,,ls,rs,,i);
                     }
                 }
             }
             else{
                 scanf("%d %d %d",&val,&ls,&rs);
                 rs++,ls++;
                 for(int i=;i<;i++) {
                     if((val&(<<i))){
                          modify1(,n,,ls,rs,,i);
                     }
                 }
             }
         }
     }
     return ;

145 }

FZU 2105 (线段树)的更多相关文章

  1. FZU 2171 线段树 区间更新求和

    很模板的题 在建树的时候输入 求和后更新 #include<stdio.h> #include<string.h> #include<algorithm> #inc ...

  2. FZU 2171(线段树的延迟标记)

    题意:容易理解. 分析:时隔很久,再一次写了一道线段树的代码,之前线段树的题也做了不少,包括各种延迟标记,但是在组队分任务之后,我们队的线段树就交给了另外一个队友在搞, 然后我就一直没去碰线段树的题了 ...

  3. HDU 3974 Assign the task(简单线段树)

    Assign the task Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. ACM: FZU 2105 Digits Count - 位运算的线段树【黑科技福利】

     FZU 2105  Digits Count Time Limit:10000MS     Memory Limit:262144KB     64bit IO Format:%I64d & ...

  5. FZU 2105 Digits Count(按位维护线段树)

    [题目链接] http://acm.fzu.edu.cn/problem.php?pid=2105 [题目大意] 给出一个序列,数字均小于16,为正数,每次区间操作可以使得 1. [l,r]区间and ...

  6. FZU 2105 Digits Count(线段树)

    Problem 2105 Digits Count Accept: 302 Submit: 1477 Time Limit: 10000 mSec Memory Limit : 262144 KB P ...

  7. F - Change FZU - 2277 (DFS序+线段树)

    题目链接: F - Change FZU - 2277 题目大意: 题意: 给定一棵根为1, n个结点的树. 有q个操作,有两种不同的操作 (1) 1 v k x : a[v] += x, a[v ' ...

  8. FZu Problem 2236 第十四个目标 (线段树 + dp)

    题目链接: FZu  Problem 2236 第十四个目标 题目描述: 给出一个n个数的序列,问这个序列内严格递增序列有多少个?不要求连续 解题思路: 又遇到了用线段树来优化dp的题目,线段树节点里 ...

  9. fzu 2082 过路费 (树链剖分+线段树 边权)

    Problem 2082 过路费 Accept: 887    Submit: 2881Time Limit: 1000 mSec    Memory Limit : 32768 KB  Proble ...

随机推荐

  1. bzoj 1697: [Usaco2007 Feb]Cow Sorting牛排序【置换群】

    至今都不知道置换群是个什么东西--题解说什么就是什么.jpg 以下来自hzwer:http://hzwer.com/3905.html #include<iostream> #includ ...

  2. 微信小程序获取自定义属性值

    写小程序的时候用到了自定义属性,特地来记录一下 特别是这个坑,必须得说一说 wxml <view class='box' bindtap='getValue'> <view clas ...

  3. python自动化测试学习笔记-8多线程

    线程模块 python的多线程只能利用cpu的一个核心,一个核心同时只能运行一个任务那么为什么你使用多线程的时候,它的确是比单线程快答:如果是一个计算为主的程序(专业一点称为CPU密集型程序),这一点 ...

  4. 线段树+树状数组+贪心 HDOJ 5338 ZZX and Permutations

    题目传送门 /* 题意:不懂... 线段树+树状数组+贪心:贪心从第一位开始枚举,一个数可以是循环节的末尾或者在循环节中,循环节(循环节内部是后面的换到前面,最前面的换到最后面).线段树维护最大值,树 ...

  5. 题解报告:hdu 2588 GCD(欧拉函数)

    Description The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written ...

  6. 一个用pyton写的监控服务端进程的软件hcm

    使用udp实现,简单,方便,不用三次握手 1. 所有部署服务器进程的机器有一个代理进程hagent,用来监听hcm console中发送过来的命令 2.hcm需要提供以下命令 start :普通方式启 ...

  7. Linux 学习(三)

    Linux进程 1.进程 进程:可执行应用程序执行后产生的对应的进程,重量级:进程是由一个线程或多个线程构成: 线程:是计算机中的最小单位,轻量级(依赖和物理性是独立存在的).损耗较低 假设进程1是由 ...

  8. Windows Socket五种I/O模型——代码全攻略(转)

    Winsock 的I/O操作: 1. 两种I/O模式 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序.套接字 默认为阻塞模式.可以通过多线程技术进行处理. 非阻塞模式:执行I/O操 ...

  9. 16位/32位/64位CPU的位究竟是说啥

    平时,我们谈论CPU,都会说某程序是32位编译,可以跑在32位机或64位机,或则是在下载某些开源包时,也分32位CPU版本或64CPU位版本,又或者在看计算机组成相关书籍时,特别时谈到X86 CPU时 ...

  10. php file_get_contents函数分段读取大记事本或其它文本文件

    当我们遇到文本文件体积很大时,比如超过几十M甚至几百M几G的大文件,用记事本或者其它编辑器打开往往不能成功,因为他们都需要把文件内容全部放到内存里面,这时就会发生内存溢出而打开错误,遇到这种情况我们可 ...