zoukankan      html  css  js  c++  java
  • fzu 2105 Digits Count ( 线段树 ) from 第三届福建省大学生程序设计竞赛

    http://acm.fzu.edu.cn/problem.php?pid=2105

    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

    Hint

    A = [1 2 4 7]

    SUM 0 2, result=1+2+4=7;

    XOR 5 0 0, A=[4 2 4 7];

    OR 6 0 3, A=[6 6 6 7];

    SUM 0 2, result=6+6+6=18.

    Source

    “高教社杯”第三届福建省大学生程序设计竞赛

    【题解】:

        这题思路想到 经过多次操作之后的区间应该是一个数字很多相同的区间:

       因为如果相邻两个数经过操作之后变成相同的数了,那么再经过覆盖了该区间的操作时,那么他们的值将同时发生改变,变成另外一个相同的值,这多次操作下去,之后将生更多的相同的数字区间,这里的相同数字就是懒惰标记更新的关键:例如:OR 6 0 3, A=[6 6 6 7];    其中6出现了3次

    详见代码:

    【code】:

      1 /**
      2 status:Accepted     language:Visual C++
      3 time:1953 ms   memory:47156KB
      4 code length:2686B   author:cj
      5 */
      6 #include <iostream>
      7 #include <cstdio>
      8 #include <cstring>
      9 #define N 1000010
     10 #define lson p<<1
     11 #define rson p<<1|1
     12 using namespace std;
     13 
     14 struct Nod
     15 {
     16     int l,r;
     17     int num;  //标记区间数字是否相同
     18 }node[N<<2];
     19 
     20 void building(int l,int r,int p)
     21 {
     22     node[p].l = l;
     23     node[p].r = r;
     24     node[p].num = -1;
     25     if(l==r)
     26     {
     27         scanf("%d",&node[p].num);
     28         return;
     29     }
     30     int mid = (l+r)>>1;
     31     building(l,mid,lson);
     32     building(mid+1,r,rson);
     33     if(node[lson].num!=-1&&node[lson].num==node[rson].num)  //向上更新
     34     {
     35         node[p].num = node[lson].num;
     36     }
     37 }
     38 
     39 int opreate(int op,int opn,int num)  //操作函数 op:操作符 opn,num:操作数
     40 {
     41     if(op==1)   return opn&num;
     42     if(op==2)   return opn|num;
     43     if(op==3)   return opn^num;
     44 
     45 }
     46 
     47 void update(int l,int r,int p,int opn,int op)
     48 {
     49     if(node[p].l==l&&node[p].r==r&&node[p].num>=0)  //当找到区间并且区间被相同的数覆盖
     50     {
     51         node[p].num = opreate(op,opn,node[p].num);
     52         return;
     53     }
     54     if(node[p].num>=0) //经过该区间时,向下更新
     55     {
     56         node[lson].num = node[rson].num = node[p].num;
     57         node[p].num = -1;
     58     }
     59     int mid = (node[p].l+node[p].r)>>1;
     60     if(r<=mid)  update(l,r,lson,opn,op);
     61     else if(l>mid)  update(l,r,rson,opn,op);
     62     else
     63     {
     64         update(l,mid,lson,opn,op);
     65         update(mid+1,r,rson,opn,op);
     66     }
     67     if(node[lson].num!=-1&&node[lson].num==node[rson].num)  //向上更新
     68     {
     69         node[p].num = node[lson].num;
     70     }
     71 }
     72 
     73 __int64 query(int l,int r,int p)
     74 {
     75     if(node[p].l==l&&node[p].r==r&&node[p].num>=0)
     76     {
     77         return node[p].num*(node[p].r-node[p].l+1);
     78     }
     79     if(node[p].num>=0)  //经过该区间时,向下更新
     80     {
     81         node[lson].num = node[rson].num = node[p].num;
     82         node[p].num = -1;
     83     }
     84     int mid = (node[p].l+node[p].r)>>1;
     85     if(r<=mid)  return query(l,r,lson);
     86     else if(l>mid)  return query(l,r,rson);
     87     else return query(l,mid,lson)+query(mid+1,r,rson);
     88     if(node[lson].num!=-1&&node[lson].num==node[rson].num)  //向上更新
     89     {
     90         node[p].num = node[lson].num;
     91     }
     92 }
     93 
     94 int main()
     95 {
     96     int t;
     97     scanf("%d",&t);
     98     while(t--)
     99     {
    100        int n,m;
    101        scanf("%d%d",&n,&m);
    102        char op[5];
    103        building(1,n,1);
    104        while(m--)
    105        {
    106             scanf("%s",op);
    107             int opn,a,b;
    108             if(op[0]=='S')
    109             {
    110                 scanf("%d%d",&a,&b);
    111                 printf("%I64d
    ",query(a+1,b+1,1));
    112             }
    113             else
    114             {
    115                 scanf("%d%d%d",&opn,&a,&b);
    116                 if(op[0]=='A')  update(a+1,b+1,1,opn,1);
    117                 else if(op[0]=='O')  update(a+1,b+1,1,opn,2);
    118                 else if(op[0]=='X')  update(a+1,b+1,1,opn,3);
    119             }
    120        }
    121     }
    122     return 0;
    123 }
  • 相关阅读:
    使用 pymssql 调用存储过程
    控制input框的输入格式
    Pycharm创建指定版本的Django
    div在页面中居中显示
    odoo12--centos7搭建odoo12
    odoo12--models模型
    odoo12--创建第一个模块
    odoo12模块目录
    odoo12代码目录说明
    win10安装odoo12教程
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3239397.html
Copyright © 2011-2022 走看看