Sequence

题意:

给一个具有n个数字的序列,并且有要进行m个操作

操作有两种:

1.修改序列中一个数字的值

2.给定一个区间[l,r],给出f(l,l)^f(l,l+1)...f(l,r)^...f(l+1,l+1)^...f(l+1,r)^....^f(r,r)

其中f(l,r)=al^a(l+1)^...a(r)


思路:第一种情况就是一个单点操作,然后第二种情况,很容易发现规律,对于r-l+1为偶数,就输出0,如果是奇数,就是f(l,l)^f(l,l+2)...f(l,r-1)。

#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<stdlib.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e5+7;
int ans[maxn*4];
int tmp[maxn*4];
int a[maxn];
void pushup(int p){
    ans[p]=ans[p<<1]^ans[p<<1|1];
    tmp[p]=tmp[p<<1]^tmp[p<<1|1];
}
void build(int l,int r,int p){
    if(l==r){
        if(l%2==1)
        ans[p]=a[l];
        else
        tmp[p]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,p<<1);
    build(m+1,r,p<<1|1);
    pushup(p);
}
int query(int l,int r,int L,int R,int p){
    if(L<=l&&r<=R){
        if(L%2==1)
        return ans[p];
        else return tmp[p];
    }
    int m=(l+r)>>1;
    int kk=0;
    if(L<=m)
       kk=kk^query(l,m,L,R,p<<1);
    if(R>m)
       kk=kk^query(m+1,r,L,R,p<<1|1);
    return kk;
}
void update(int l,int r,int i,int j,int p){
    if(l==r){
        if(i%2==1)
        ans[p]=j;
        else tmp[p]=j;
        return ;
    }
    int m=(l+r)>>1;
    if(i<=m)
        update(l,m,i,j,p<<1);
    else
        update(m+1,r,i,j,p<<1|1);
    pushup(p);
}
int main(){
    int t;
    scanf("%d",&t);
    int kase=1;
    while(t--){
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
        build(1,n,1);
        printf("Case #%d:
",kase++);
        while(m--){
            int x,l,r;
            scanf("%d%d%d",&x,&l,&r);
            if(x==1){
                int ans=0;
                if((r-l+1)%2==1){
                  ans=query(1,n,l,r,1);
                  printf("%d
",ans);
                }else
                     printf("0
");
            }else{
                update(1,n,l,r,1);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/2462478392Lee/p/11743328.html