UVALive - 7639 G - Extreme XOR Sum(思维)

题目链接

题意

给出一个序列,相邻两两异或,生成一个新序列,再相邻两两异或,直到只剩下一个元素,问最后结果为多少。m个查询,每次都有一个待查询区间。

 

分析

既然有多组查询,n只是1e4,那么可以考虑预处理。
预处理出每种长度的区间最后剩下的元素位置。然后就O(1)查询了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int maxn=1e4+10;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int a[maxn],num[maxn];
vector<int> v[maxn];
void init(){
    for(int i=1;i<maxn;i++){
        num[1]=num[i]=1;
        for(int j=i-1;j>1;j--) num[j]^=num[j-1];
        for(int j=1;j<=i;j++)
            if(num[j]) v[i].push_back(j);
    }
}

int main(){
    init();
    int t;
    scanf("%d",&t);
    for(int k=1;k<=t;k++){
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        int q;
        scanf("%d",&q);
        printf("Case %d:\n",k);
        while(q--){
            int l,r;
            scanf("%d%d",&l,&r);
            int ans=0;
            for(int i=0;i<v[r-l+1].size();i++) ans^=a[l+v[r-l+1][i]-1];
            printf("%d\n",ans);
        }
    }
    return 0;
}

 

posted @ 2017-08-04 15:22  litos  阅读(220)  评论(0编辑  收藏  举报