zoukankan      html  css  js  c++  java
  • 清北学堂模拟赛d1t6 或和异或(xor)

    题目描述

    LYK最近在研究位运算,它研究的主要有两个:or和xor。(C语言中对于|和^)

    为了更好的了解这两个运算符,LYK找来了一个2^n长度的数组。它第一次先对所有相邻两个数执行or操作,得到一个2^(n-1)长度的数组。也就是说,如果一开始时a[1],a[2],…,a[2^n],执行完第一次操作后,会得到a[1] or a[2],a[3] or a[4] ,…, a[(2^n)-1] or a[2^n]。

    第二次操作,LYK会将所有相邻两个数执行xor操作,得到一个2^(n-2)长度的数组,假如第一次操作后的数组是b[1],b[2],…,b[2^(n-1)],那么执行完这次操作后会变成b[1] xor b[2], b[3] xor b[4] ,…, b[(2^(n-1))-1] xor b[2^(n-1)]。

    第三次操作,LYK仍然将执行or操作,第四次LYK执行xor操作。如此交替进行。

    最终这2^n个数一定会变成1个数。LYK想知道最终这个数是多少。

    为了让这个游戏更好玩,LYK还会执行Q次修改操作。每次修改原先的2^n长度的数组中的某一个数,对于每次修改操作,你需要输出n次操作后(最后一定只剩下唯一一个数)剩下的那个数是多少。

    输入格式(xor.in)

        第一行两个数n,Q。

    接下来一行2^n个数ai表示一开始的数组。

    接下来Q行,每行两个数xi,yi,表示LYK这次的修改操作是将a{xi}改成yi。

    输出格式(xor.out)

    Q行,表示每次修改操作后执行n次操作后剩下的那个数的值。

    输入样例

    2 4

    1 6 3 5

    1 4

    3 4

    1 2

    1 2

    输出样例

    1

    3

    3

    3

    样例解释

    第一次修改,{4,6,3,5}->{6,7}->{1}

    第二次修改,{4,6,4,5}->{6,5}->{3}

    第三次修改,{2,6,4,5}->{6,5}->{3}

    第四次修改,{2,6,4,5}->{6,5}->{3}

    对于30%的数据n<=17,Q=1。

    对于另外20%的数据n<=10,Q<=1000。

    对于再另外30%的数据n<=12,Q<=100000。

    对于100%的数据1<=n<=17,1<=Q<=10^5,1<=xi<=2^n,0<=yi<2^30,0<=ai<2^30。

    分析:考试的时候这道题是T3,题面又很长,就没信心做下去直接打了个暴力,竟然还有50分,现在看,竟然就是一道裸的线段树的题......

          它的每一次操作都对应线段树的合并操作,我们只需要记录一下深度,看看进行哪一次操作就可以了.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int n, q,maxn,c[1000010];
    
    void build(int o, int l, int r, int dep)
    {
        if (l == r)
        {
            scanf("%d", &c[o]);
            return;
        }
        int mid = (l + r) >> 1;
        build(o * 2, l, mid, dep + 1);
        build(o * 2 + 1, mid + 1, r, dep + 1);
        if ((n - dep + 1) % 2 == 1)
            c[o] = c[o * 2] | c[o * 2 + 1];
        else
            c[o] = c[o * 2] ^ c[o * 2 + 1];
    }
    
    void update(int o, int l, int r, int x, int v, int dep)
    {
        if (l == r)
        {
            c[o] = v;
            return;
        }
        int mid = (l + r) >> 1;
        if (x <= mid)
            update(o * 2, l, mid, x, v, dep + 1);
        if (x > mid)
            update(o * 2 + 1, mid + 1, r, x, v, dep + 1);
        if ((n - dep + 1) % 2 == 1)
            c[o] = c[o * 2] | c[o * 2 + 1];
        else
            c[o] = c[o * 2] ^ c[o * 2 + 1];
    }
    
    int main()
    {
        scanf("%d%d", &n, &q);
        maxn = (1 << n);
        build(1, 1, maxn,1);
        for (int i = 1; i <= q; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            update(1, 1, maxn, x, y, 1);
            printf("%d
    ", c[1]);
        }
        
        return 0;
    }
  • 相关阅读:
    javaScirpt学习之事件
    验证表单内容之后如何阻止表单提交
    利用js制作异步验证ajax方法()
    Ajax制作无刷新评论系统
    ajax查询数据的举例
    以Ajax的方式访问数据库
    jquery中的全局事件
    jquery序列化元素
    jquery中的ajax
    jquery与ajax的应用
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7618271.html
Copyright © 2011-2022 走看看