码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

时间:2016-04-08 22:59:40      阅读:389      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:http://codeforces.com/problemset/problem/242/E

给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x。

这题是线段树成段更新,但是不能直接更新,不然只能一个数一个数更新。这样只能把每个数存到一个数组中,长度大概是20吧,然后模拟二进制的位操作。仔细一点就行了。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <cstring>
  5 using namespace std;
  6 const int MAXN = 1e5 + 5;
  7 typedef __int64 LL;
  8 struct segtree {
  9     int l , r , lazy , bit[21];
 10 }T[MAXN << 2];
 11 LL Res;
 12 
 13 void init(int p , int l , int r) {
 14     int mid = (l + r) >> 1;
 15     T[p].r = r , T[p].l = l , T[p].lazy = 0;
 16     if(l == r) {
 17         int num;
 18         scanf("%d" , &num);
 19         for(int i = 0 ; i < 21 ; i++) {
 20             T[p].bit[i] = ((num & 1) ? 1:0 );
 21             num >>= 1;
 22         }
 23         return ;
 24     }
 25     init(p << 1 , l , mid);
 26     init((p << 1)|1 , mid + 1 , r);
 27     for(int i = 0 ; i < 21 ; i++) {
 28         T[p].bit[i] = T[p << 1].bit[i] + T[(p << 1)|1].bit[i];
 29     }
 30 }
 31 
 32 void updata(int p , int l , int r , int x) {
 33     int mid = (T[p].l + T[p].r) >> 1;
 34     if(l == T[p].l && T[p].r == r) {
 35         T[p].lazy ^= x;
 36         for(int i = 0 ; i < 21 ; i++) {
 37             if(x % 2)
 38                 T[p].bit[i] = (T[p].r - T[p].l + 1) - T[p].bit[i];
 39             x >>= 1;
 40         }
 41         return ;
 42     }
 43     if(T[p].lazy) {
 44         T[p << 1].lazy ^= T[p].lazy;
 45         T[(p << 1)|1].lazy ^= T[p].lazy;
 46         for(int i = 0 ; i < 21 ; i++) {
 47             if(T[p].lazy & 1) {
 48                 T[p << 1].bit[i] = (T[p << 1].r - T[p << 1].l + 1) - T[p << 1].bit[i];
 49                 T[(p << 1)|1].bit[i] = (T[(p << 1)|1].r - T[(p << 1)|1].l + 1) - T[(p << 1)|1].bit[i];
 50             }
 51             T[p].lazy >>= 1;
 52         }
 53     }
 54     if(r <= mid) { 
 55         updata(p << 1 , l , r , x);
 56     }
 57     else if(l > mid) {
 58         updata((p << 1)|1 , l , r , x);
 59     }
 60     else {
 61         updata(p << 1 , l , mid , x);
 62         updata((p << 1)|1 , mid + 1 , r , x);
 63     }
 64     for(int i = 0 ; i < 21 ; i++) {
 65         T[p].bit[i] = T[p << 1].bit[i] + T[(p << 1)|1].bit[i];
 66     }
 67 }
 68 
 69 void query(int p , int l , int r) {
 70     int mid = (T[p].l + T[p].r) >> 1;
 71     if(l == T[p].l && T[p].r == r) {
 72         for(int i = 0 ; i < 21 ; i++) {
 73             if(T[p].bit[i])
 74                 Res += (LL)T[p].bit[i] * (LL)(1 << i);
 75         }
 76         return ;
 77     }
 78     if(T[p].lazy) {
 79         T[p << 1].lazy ^= T[p].lazy;
 80         T[(p << 1)|1].lazy ^= T[p].lazy;
 81         for(int i = 0 ; i < 21 ; i++) {
 82             if(T[p].lazy & 1) {
 83                 T[p << 1].bit[i] = (T[p << 1].r - T[p << 1].l + 1) - T[p << 1].bit[i];
 84                 T[(p << 1)|1].bit[i] = (T[(p << 1)|1].r - T[(p << 1)|1].l + 1) - T[(p << 1)|1].bit[i];
 85             }
 86             T[p].lazy >>= 1;
 87         }
 88     }
 89     if(r <= mid) {
 90         query(p << 1 , l , r);
 91     }
 92     else if(l > mid) {
 93         query((p << 1)|1 , l , r);
 94     }
 95     else {
 96         query(p << 1 , l , mid);
 97         query((p << 1)|1 , mid + 1 , r);
 98     }
 99     for(int i = 0 ; i < 21 ; i++) {
100         T[p].bit[i] = T[p << 1].bit[i] + T[(p << 1)|1].bit[i];
101     }
102 }
103 
104 int main()
105 {
106     int n , m , c , x , l , r;
107     scanf("%d" , &n);
108     init(1 , 1 , n);
109     scanf("%d" , &m);
110     while(m--) {
111         scanf("%d" , &c);
112         if(c == 1) {
113             scanf("%d %d" , &l , &r);
114             Res = 0;
115             query(1 , l , r);
116             printf("%I64d\n" , Res);
117         }
118         else {
119             scanf("%d %d %d" , &l , &r , &x);
120             updata(1 , l , r , x);
121         }
122     }
123 }

 

Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)

标签:

原文地址:http://www.cnblogs.com/Recoder/p/5370270.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!