【题解】洛谷P6225: [eJOI2019] 异或橙子

P6225 [eJOI2019] 异或橙子

结论题,要手玩几组样例就懂了,发现长度为偶数的最后削为0,否则的话下标为奇数答案就是区间下标为奇数的异或和,偶数相同,所以考虑用两个树状数组分别维护下标奇偶数的异或前缀和,然后再异或区间。

#include <bits/stdc++.h>
//#define int long long
#define ls p<<1
#define rs p<<1|1 
#define re register 
#define pb push_back
#define pir pair<int,int>
#define f(a,x,i) for(int i=a;i<=x;i++)
#define fr(a,x,i) for(int i=a;i>=x;i--)
#define lb(x) x&(-x);
const int N=2e5+10;
const int mod=1e9+7;
using namespace std;

int n,m;
int a[N];
int t1[N];
int t2[N];

void add(int *t,int x,int k){
	while(x<=200000){
		t[x]^=k;
		x+=lb(x);
	}
}

int query(int *t,int x){
	int sum=0;
	while(x){
		sum^=t[x];
		x-=lb(x);
	}
	return sum;
}

signed main(){
//	freopen("xp1.in","r",stdin);
    ios::sync_with_stdio(0);
    cin.tie(nullptr);
    cin>>n>>m;
    
    for(int i=1;i<=n;i++){
    	cin>>a[i];
    	if(i&1){
    		add(t1,i,a[i]);
		}
		else{
			add(t2,i,a[i]);
		}
	}
    
    while(m--){
    	int op,l,r;
    	cin>>op>>l>>r;
    	if(op&1){
    		if(l&1){
    			add(t1,l,a[l]);
				a[l]=r;
				add(t1,l,r); 
			} 
			else{
				add(t2,l,a[l]);
				a[l]=r;
				add(t2,l,r); 
			}
		}
		else{
			if((r-l)&1){
				cout<<"0\n";
				continue;
			}
			else{
				if(l&1){
					cout<<(query(t1,r)^query(t1,l-1))<<"\n";
				}
				else{
					cout<<(query(t2,r)^query(t2,l-1))<<"\n";
				}
			} 	
		}
	}
	return 0;
}
posted @ 2024-12-07 19:18  sad_lin  阅读(65)  评论(0)    收藏  举报