[树状数组]操作数列

Problem E: 操作数列

Time Limit: 3 Sec   Memory Limit: 128 MB
Submit: 39   Solved: 10
[ Submit][ Status][ Web Board]

Description

对于一个长度为n(n<=200000)的数列。最开始,数列中的全部数都是0,然后定义如下两个操作:
1 x y c (0< x <= y <= 200000, c < 2147483645)
2 x (0 < x <= 200000)
1 x y c 操作表示,将区间[x,y]中的全部元素都异或c;
2 x 操作表示,将第x个元素输出。

Input

第一行一个 t ,表示case数;
对于每个case,第一行一个n (n <= 200000),表示数列大小;
第二行一个数 q (q <= 100000),表示接下来有q次操作;
接下来q行,每行按描述中给出一个操作。

Output

对于每个 2 x 操作,输出该操作的结果,每两个case间有一个换行。

Sample Input

21041 1 5 11 3 5 12 12 5541 1 4 12 11 1 4 22 1

Sample Output

1013

HINT


操作都用异或。

考虑到异或具有两次异或等于不异或的性质。

我们可以使用前缀的方法。

修改区间查询点和修改点查询区间是两个相反的过程。


#include <cstdio>
#include <cstring>
#define lowbit(x) ((x)&(-(x)))
 
int n;
const int maxn = 200010;
int tree[maxn];
 
void modify(int l,int c)
{
    while (l >= 1)
    {
        tree[l] ^= c;
        l -= lowbit(l);
    }
}
 
int query(int l)
{
    int ans = 0;
    while (l <= n)
    {
        ans ^= tree[l];
        l += lowbit(l);
    }
    return ans;
}
 
int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        memset(tree,0,sizeof tree);
        int q;
        scanf("%d%d",&n,&q);
        while (q--)
        {
            int o;
            scanf("%d",&o);
            if (o == 1)
            {
                int x,y,c;
                scanf("%d%d%d",&x,&y,&c);
                modify(y,c);
                modify(x-1,c);
            }
            else
            {
                int x;
                scanf("%d",&x);
                printf("%d\n",query(x));
            }
        }
        printf("\n");
    }
    return 0;
}
/**************************************************************
    Problem: 1263
    User: wuyihao
    Language: C++
    Result: Accepted
    Time:599 ms
    Memory:1836 kb
****************************************************************/


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值