zoukankan      html  css  js  c++  java
  • The 2019 ICPC China Nanchang National Invitational and International Silk-Road Programming Contest

    题目链接:Sequence

    题意:给你一个长度为$n$的数组,定义函数$f(l,r)=a_{l} oplus a_{l+1} oplus...oplus a_{r}$,$F(l,r)=f(l,l)oplus f(l,l+1)oplus ...oplus f(l,r)oplus f(l+1,l+1)oplus ...f(l+1,r)oplus ...oplus f(r,r)$,有两种操作,第一种将数组中某个元素$a[x]$变为$y$,第二种计算$F(l,r)$的值。

    思路:打表后发现只有当$l$和$r$同时为奇数或者偶数时$F(l,r)$才不为$0$,其他情况下$F(l,r)$都为$0$,并且$F(l,r)=a[l]oplus a[l+2]oplus ...oplus a[r-2]oplus a[r]$,由于涉及到修改和查询两种操作,所以用线段树来维护,每个结点维护两个值:$w$表示区间内奇数项异或的结果,$ww$表示区间内偶数项异或的结果。

    初始建树时

    • 当前项为奇数项,则输入$tree[k].w$的值,同时令$tree[k].ww=0$
    • 当前项为偶数项,则输入$tree[k].ww$的值,同时令$tree[k].w=0$

    修改操作时

    • 需要修改的项为奇数项,则对$tree[k].w$进行修改
    • 需要修改的项为偶数项,则对$tree[k].ww$进行修改

    查询操作时

    • 如果$l$为奇数,则用$ans=ansoplus tree[k].w$来更新答案
    • 如果$l$为偶数,则用$ans=ansoplus tree[k].ww$来更新答案
    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    const int N = 100010;
    
    struct node {
        int l, r, w, ww;
    };
    
    int a, b, x, y, ans;
    node tree[4 * N];
    
    void build(int k, int lef, int rig)
    {
        tree[k].l = lef, tree[k].r = rig;
        if (tree[k].l == tree[k].r) {
            if (0 == tree[k].l % 2) {
                tree[k].w = 0, scanf("%d", &tree[k].ww);
            }
            else {
                tree[k].ww = 0, scanf("%d", &tree[k].w);
            }
            return;
        }
        int mid = (lef + rig) / 2;
        build(k * 2, lef, mid); build(k * 2 + 1, mid + 1, rig);
        tree[k].w = tree[k * 2].w ^ tree[k * 2 + 1].w;
        tree[k].ww = tree[k * 2].ww ^ tree[k * 2 + 1].ww;
    }
    
    void change_point(int k)
    {
        if (tree[k].l == tree[k].r) {
            if (tree[k].l % 2 == 0) tree[k].ww = y;
            else tree[k].w = y;
            return;
        }
        int mid = (tree[k].l + tree[k].r) / 2;
        if (x <= mid) change_point(2 * k);
        else change_point(2 * k + 1);
        tree[k].w = tree[2 * k].w ^ tree[2 * k + 1].w;
        tree[k].ww = tree[2 * k].ww ^ tree[2 * k + 1].ww;
    }
    
    void ask_interval(int k)
    {
        if (tree[k].l >= a && tree[k].r <= b) {
            if (0 == a % 2) ans ^= tree[k].ww;
            else ans ^= tree[k].w;
            return;
        }
        int mid = (tree[k].l + tree[k].r) / 2;
        if (a <= mid) ask_interval(2 * k);
        if (b > mid) ask_interval(2 * k + 1);
    }
    
    int main()
    {
        int T, t, n, q, icas = 0;
        scanf("%d", &T);
        while (T--) {
            printf("Case #%d:
    ", ++icas);
            scanf("%d%d", &n, &q), build(1, 1, n);
            while (q--) {
                scanf("%d", &t);
                if (0 == t) {
                    scanf("%d%d", &x, &y);
                    change_point(1);
                }
                else {
                    ans = 0, scanf("%d%d", &a, &b);
                    if (a % 2 == b % 2) ask_interval(1);
                    printf("%d
    ", ans);
                }
            }
        }
        return 0;
    }

  • 相关阅读:
    Excel Sheet Column Number
    HappyNum
    isIsomorphic
    Contains DuplicateII
    iis7 设置http 自动跳转到https
    php 安装redis
    java 打包 war包
    NPOI 操作excel之 将图片插入到指定位置;
    nopi 简洁笔记
    vs11 微软下载地址
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/11706173.html
Copyright © 2011-2022 走看看