zoukankan      html  css  js  c++  java
  • fzu 2105 Digits Count 线段树

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2105

    题意:

    给出一个数组A[0]-A[n-1],每个数最大是16。有4种操作:

    AND opn L R:L-R区间内的数都AND上opn这个数

    OR opn L R:L-R区间内的数都OR上opn这个数

    XOR opn L R:L-R区间内的数都XOR上opn这个数

    SUM L R:求L-R区间内所有数的和。

    0 <= opn <= 16

    思路:

    可以发现A[i]和opn最大都不超过16,所以可以设4个数组,分别用来存数的第0位,第1位,第2位,第3位。

    对每个数组用线段树来维护。

    可以知道AND 操作,如果AND 1,那么原来的那一位不变,如果AND 0,那么原来那一位变成0。

    OR操作,如果OR 1,那么原来那一位变成0,如果OR 0,则原来那一位不变。

    XOR操作,如果XOR 0,那么原来那位不变,如果XOR 1,原来那一位要取反。

    所以成端更新就是3个操作,该段全部取反,该段全变0,该段全变1。

    取反操作要特殊处理一下,

    如果当前节点的标记是取反操作,如果它的子节点是变0操作,那么此时它的子节点标记的操作应该为变1。

    如果它的子节点是变1操作,那么此时它的子节点标记的操作应该为变0。

    如果它的子节点是取反操作,那么两次取反相当于不变。

    如果它的子节点无标记,那么子节点才应该标记为取反操作。

    最后求SUM的时候,把每一位上为1的数乘相应的权重加起来就可以了。

      1 //#include <bits/stdc++.h>
      2 #include <iostream>
      3 #include <cstring>
      4 #include <cstdio>
      5 #include <string>
      6 #include <cmath>
      7 using namespace std;
      8 int T;
      9 #define maxn 1000010
     10 #define lson l, m, rt<<1
     11 #define rson m+1, r, rt<<1|1
     12 int sum[5][maxn<<2], col[5][maxn<<2];
     13 void pushup(int rt)
     14 {
     15     for(int i = 0; i < 4; i++) sum[i][rt] = sum[i][rt<<1] + sum[i][rt<<1|1];
     16 }
     17 void build(int l, int r, int rt)
     18 {
     19     for(int i = 0; i < 4; i++) col[i][rt] = -1;
     20     if(l == r)
     21     {
     22         int temp; scanf("%d", &temp);
     23         for(int i = 0; i < 4; i++)
     24         {
     25             sum[i][rt] = temp & 1;
     26             temp >>= 1;
     27         }
     28         return;
     29     }
     30     int m = (l+r)>>1;
     31     build(lson);
     32     build(rson);
     33     pushup(rt);
     34 }
     35 void pushdown(int rt, int len)
     36 {
     37     for(int i = 0; i < 4; i++)
     38     {
     39         if(col[i][rt] == -1) continue;
     40         if(col[i][rt] == 1)
     41         {
     42             sum[i][rt<<1] = len-(len>>1);
     43             sum[i][rt<<1|1] = len>>1;
     44             col[i][rt<<1] = col[i][rt<<1|1] = 1;
     45         }
     46         else if(col[i][rt] == 0) 
     47         {
     48             sum[i][rt<<1] = sum[i][rt<<1|1] = 0; 
     49             col[i][rt<<1] = col[i][rt<<1|1] = 0;
     50         }
     51         else if(col[i][rt] == 2)
     52         {
     53             sum[i][rt<<1] = (len-(len>>1)) - sum[i][rt<<1];
     54             sum[i][rt<<1|1] = (len>>1) - sum[i][rt<<1|1];
     55             if(col[i][rt<<1] == 1) col[i][rt<<1] = 0;
     56             else if(col[i][rt<<1] == 0) col[i][rt<<1] = 1;
     57             else if(col[i][rt<<1] == 2) col[i][rt<<1] = -1;
     58             else  col[i][rt<<1] = 2;
     59             
     60             if(col[i][rt<<1|1] == 1) col[i][rt<<1|1] = 0;
     61             else if(col[i][rt<<1|1] == 0)  col[i][rt<<1|1] = 1;
     62             else if(col[i][rt<<1|1] == 2) col[i][rt<<1|1] = -1;
     63             else col[i][rt<<1|1] = 2;
     64         }
     65         col[i][rt] = -1;
     66     }
     67 }
     68 void update(int L, int R, int val, int l, int r, int rt, int op)
     69 {
     70     if(L <= l && R >= r)
     71     {
     72         if(l < r) pushdown(rt, r-l+1);
     73         int tempval = val;
     74         for(int i = 0; i < 4; i++)
     75         {
     76             if(op == 0)         // AND
     77             {
     78                 if((tempval&1) == 0) 
     79                 {
     80                     sum[i][rt] = 0; col[i][rt] = 0;
     81                 }   
     82             }
     83             else if(op == 1)    //OR
     84             {
     85                 if((tempval&1) == 1)
     86                 {
     87                     sum[i][rt] = r-l+1; col[i][rt] = 1;
     88                 }
     89             }
     90             else if(op == 2)     //XOR
     91             {
     92                 if((tempval&1) == 1)
     93                 {
     94                     sum[i][rt] = (r-l+1) - sum[i][rt]; col[i][rt] = 2;
     95                 }
     96             }
     97             tempval >>= 1;
     98         }       
     99         return;
    100     }
    101     pushdown(rt, r-l+1);
    102     int m = (l+r)>>1;
    103     if(L <= m) update(L, R, val, lson, op);
    104     if(R > m) update(L, R, val, rson, op);
    105     pushup(rt);
    106 }
    107 int query(int L, int R, int l, int r, int rt)
    108 {
    109     if(L <= l && R >= r)
    110     {
    111         int SUM = 0;
    112         for(int i = 0; i < 4; i++)
    113         {
    114             SUM += sum[i][rt]*pow(2.0,i);
    115         }
    116         return SUM;
    117     }
    118     pushdown(rt, r-l+1);
    119     int m = (l+r)>>1;
    120     int ret = 0;
    121     if(L <= m) ret += query(L, R, lson);
    122     if(R > m) ret += query(L, R, rson);
    123     return ret;
    124 }
    125 int main() 
    126 {
    127     //freopen("in.txt", "r", stdin);
    128     //freopen("out.txt", "w", stdout);
    129     int n, m;
    130     scanf("%d", &T);
    131     while(T--)
    132     {
    133         scanf("%d%d", &n, &m);
    134         build(1, n, 1);
    135         char op[10];
    136         int opn, l, r;
    137         while(m--)
    138         {
    139             scanf("%s", op);
    140             if(op[0] == 'A')
    141             {
    142                 scanf("%d%d%d", &opn, &l, &r);
    143                 update(l+1, r+1, opn, 1, n, 1, 0);
    144             }
    145             else if(op[0] == 'O')
    146             {
    147                 scanf("%d%d%d", &opn, &l, &r);
    148                 update(l+1, r+1, opn, 1, n, 1, 1);
    149             }
    150             else if(op[0] == 'X')
    151             {
    152                 scanf("%d%d%d", &opn, &l, &r);
    153                 update(l+1, r+1, opn, 1, n, 1, 2);
    154             }
    155             else if(op[0] == 'S')
    156             {
    157                 scanf("%d%d", &l, &r);
    158                 printf("%d
    ", query(l+1, r+1, 1, n, 1));
    159             }
    160         }
    161         
    162     }
    163     return 0;
    164 }
  • 相关阅读:
    爬虫入门(五)
    爬虫入门(四)
    爬虫入门(三)
    爬虫入门(二)
    爬虫入门(一)
    openpyxl的简单使用
    ansible(三)
    ansible(二)
    ansible(一)
    CF Global Round 10-F
  • 原文地址:https://www.cnblogs.com/titicia/p/5521200.html
Copyright © 2011-2022 走看看