• [线段树]Codeforces 339D Xenia and Bit Operations


    Xenia and Bit Operations
    time limit per test
    2 seconds
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Xenia the beginner programmer has a sequence a, consisting of 2n non-negative integers: a1, a2, ..., a2n. Xenia is currently studying bit operations. To better understand how they work, Xenia decided to calculate some value v for a.

    Namely, it takes several iterations to calculate value v. At the first iteration, Xenia writes a new sequence aor a2, aor a4, ..., a2n - 1 or a2n, consisting of 2n - 1 elements. In other words, she writes down the bit-wise OR of adjacent elements of sequence a. At the second iteration, Xenia writes the bitwise exclusive OR of adjacent elements of the sequence obtained after the first iteration. At the third iteration Xenia writes the bitwise OR of the adjacent elements of the sequence obtained after the second iteration. And so on; the operations of bitwise exclusive OR and bitwise OR alternate. In the end, she obtains a sequence consisting of one element, and that element is v.

    Let's consider an example. Suppose that sequence a = (1, 2, 3, 4). Then let's write down all the transformations (1, 2, 3, 4)  →  (1 or 2 = 3, 3 or 4 = 7)  →  (3 xor 7 = 4). The result is v = 4.

    You are given Xenia's initial sequence. But to calculate value v for a given sequence would be too easy, so you are given additional m queries. Each query is a pair of integers p, b. Query p, b means that you need to perform the assignment ap = b. After each query, you need to print the new value v for the new sequence a.

    Input

    The first line contains two integers n and m (1 ≤ n ≤ 17, 1 ≤ m ≤ 105). The next line contains 2n integers a1, a2, ..., a2n (0 ≤ ai < 230). Each of the next m lines contains queries. The i-th line contains integers pi, bi (1 ≤ pi ≤ 2n, 0 ≤ bi < 230) — the i-th query.

    Output

    Print m integers — the i-th integer denotes value v for sequence a after the i-th query.

    Examples
    input
    Copy
    2 4
    1 6 3 5
    1 4
    3 4
    1 2
    1 2
    output
    Copy
    1
    3
    3
    3
    Note

    For more information on the bit operations, you can follow this link: http://en.wikipedia.org/wiki/Bitwise_operation

    题意:

    给出2的n次方个数,每次将现在这个序列中相邻的两个数运算后合并为一个数,得到一个新的序列,这个新序列的长度是上一个序列长度-1,当新序列长度为1时停止运算,奇数次操作进行OR运算,偶数次操作进行XOR运算,
    现在有m个询问,每次询问会改变上一个序列中的一个值,问新序列运算后的值为多少

    思路:

    树上的每一层是一个新序列,从叶子节点那一层记为0,向上更新层数,每层的层数是它下面那层的层数+1
    记录了层数之后就知道每一层要进行什么计算了,奇数层OR,偶数层XOR,
    最后对每次询问单点修改,向上更新后输出根节点的值就可以了

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int amn=1<<17+5;
     4 typedef long long ll;
     5 int a[amn];
     6 struct tree{
     7     ll l,r,sum,deep;
     8     #define ls rt<<1
     9     #define rs rt<<1|1
    10     #define trl tr[rt].l
    11     #define trr tr[rt].r
    12     #define trsum tr[rt].sum
    13     #define trlssum tr[ls].sum
    14     #define trrssum tr[rs].sum
    15     #define trdp tr[rt].deep
    16 }tr[amn];
    17 void push_up(int rt){
    18     trdp=tr[ls].deep+1;     ///记录计算层数,叶子节点设为0,父节点的层数为儿子节点层数+1
    19     if(trdp&1)              ///奇数层数OR运算,偶数层数XOR运算
    20         trsum=trlssum|trrssum;
    21     else
    22         trsum=trlssum^trrssum;
    23 }
    24 void build(int rt,int l,int r){
    25     trl=l,trr=r;
    26     if(trl==trr){
    27         trsum=a[l];
    28         trdp=0;             ///叶子节点计算层数
    29         return ;
    30     }
    31     int mid=(l+r)>>1;
    32     build(ls,l,mid);
    33     build(rs,mid+1,r);
    34     push_up(rt);
    35 }
    36 void updata(int rt,int l,int r,int pos,ll val){
    37     int mid=(l+r)>>1;
    38     if(trl==trr&&trl==pos){
    39         trsum=val;
    40         return;
    41     }
    42     if(pos<=mid)updata(ls,l,mid,pos,val);
    43     else updata(rs,mid+1,r,pos,val);
    44     push_up(rt);
    45 }
    46 int main(){
    47     int n,m,p,b;
    48     ios::sync_with_stdio(0);
    49     cin>>n>>m;
    50     int len=1<<n;           ///注意这里长度为2的n次方
    51     for(int i=1;i<=len;i++)
    52         cin>>a[i];
    53     build(1,1,len);
    54     while(m--){
    55         cin>>p>>b;
    56         updata(1,1,len,p,b);
    57         printf("%d
    ",tr[1].sum);
    58     }
    59 }
    60 /***
    61 给出2的n次方个数,每次将现在这个序列中相邻的两个数运算后合并为一个数,得到一个新的序列,这个新序列的长度是上一个序列长度-1,当新序列长度为1时停止运算,奇数次操作进行OR运算,偶数次操作进行XOR运算,
    62 现在有m个询问,每次询问会改变上一个序列中的一个值,问新序列运算后的值为多少
    63 在纸上模拟可以看出这是一个完全二叉树的结构,单点修改,向上更新数值,可以想到用线段树来维护
    64 树上的每一层是一个新序列,从叶子节点那一层记为0,向上更新层数,每层的层数是它下面那层的层数+1
    65 记录了层数之后就知道每一层要进行什么计算了,奇数层OR,偶数层XOR,
    66 最后对每次询问单点修改,向上更新后输出根节点的值就可以了
    67 ***/
  • 相关阅读:
    线性代数基础知识的复习
    第一个机器学习算法:线性回归与梯度下降
    初识机器学习
    VScode中LeetCode插件无法登录的情况
    内存管理-内存管理功能
    分组密码
    Linux进程调度
    进程调度
    死锁
    临界区和缩
  • 原文地址:https://www.cnblogs.com/Railgun000/p/11367587.html
Copyright © 2020-2023  润新知