Given a sequence of nnn numbers a1,a2,⋯ ,ana_1, a_2,\cdots, a_na1,a2,⋯,an and three functions.
Define a function f(l,r)f(l,r)f(l,r) which returns ⊕a[x](l≤x≤r)\oplus a[x] (l \le x \le r)⊕a[x](l≤x≤r). The \oplus⊕ represents exclusive OR.
Define a function g(l,r)g(l,r)g(l,r) which returns ⊕f(x,y)(l≤x≤y≤r)⊕f(x,y)\oplus f(x,y)(l \le x \le y \le r)⊕f(x,y)⊕f(x,y)(l≤x≤y≤r)⊕f(x,y).
Define a function w(l,r)w(l,r)w(l,r) which returns ⊕g(x,y)(l≤x≤y≤r)⊕g(x,y)\oplus g(x,y)(l \le x \le y \le r)⊕g(x,y)⊕g(x,y)(l≤x≤y≤r)⊕g(x,y).
You are also given a number of xor-queries. A xor-query is a pair (i,j)(1≤i≤j≤n)(i,j) (1 \le i \le j \le n)(i,j)(1≤i≤j≤n). For each xor-query (i,j)(i, j)(i,j), you have to answer the result of function w(l,r)w(l,r)w(l,r).
Input
Line 111: t(1≤t≤20)t (1 \le t \le 20)t(1≤t≤20).
For each test case:
Line 111: n(1≤n≤100000)n (1 \le n \le 100000)n(1≤n≤100000).
Line 222: nnn numbers a1,a2,⋯ ,an(1≤ai≤109)a_1, a_2, \cdots, a_n (1 \le a_i \le 10^9)a1,a2,⋯,an(1≤ai≤109)
Line 333: q(1≤q≤100000)q (1 \le q \le 100000)q(1≤q≤100000), the number of xor-queries.
In the next q lines, each line contains 222 numbers i,ji, ji,j representing a xor-query (1≤i≤j≤n)(1 \le i \le j \le n)(1≤i≤j≤n).
It is guaranteed that sum of nnn and q≤106q \le 10^6q≤106
Output
For each xor-query (i,j)(i, j)(i,j), print the result of function w(i,j)w(i,j)w(i,j) in a single line.
样例输入
1
5
1 2 3 4 5
5
1 3
1 5
1 4
4 5
3 5
样例输出
2
4
0
1
4
解题思路:
emmmm,我这道题是通过打表寻找规律来解答的。。。
打表的代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#include <utility>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
#define ms(arr) memset(arr,0,sizeof(arr))
//priority_queue<int,vector<int> ,greater<int> >q;
const int maxn = (int)1e5 + 5;
const ll mod = 1e9+7;
int arr[100];
int main()
{#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);#endiffreopen("out.txt", "w", stdout);ios::sync_with_stdio(0),cin.tie(0);for(int l1=1,r1=1;r1<=50;r1++) {memset(arr,0,sizeof arr);for(int l2=l1;l2<=r1;l2++) {for(int r2=l2;r2<=r1;r2++) {for(int l3=l2;l3<=r2;l3++) {for(int r3=l3;r3<=r2;r3++) {for(int k=l3;k<=r3;k++) {arr[k]++;}}}}}//输出的1代表最后的答案这项存在,0代表不存在for(int i=1;i<=r1;i++) {if(arr[i]%2==0) printf("0 ");else printf("1 ");}printf("\n");//例如假设区间为[l,r],第一行代表当区间长度为1时,其答案就是a[l]//当区间长度为2时,其答案为a[l]^a[r]//当区间长度为3时,其答案为a[l+1]//当区间长度为4时,其答案为0}return 0;
}
通过表格我们可以发现,
当(r−l+1)%4=0(r-l+1) \%4=0(r−l+1)%4=0时,答案为000;
当(r−l+1)%4=1(r-l+1) \%4=1(r−l+1)%4=1时,答案为a[l]⊕a[l+4]⊕a[l+8]⋯a[r]a[l]\oplus a[l+4] \oplus a[l+8] \cdots a[r]a[l]⊕a[l+4]⊕a[l+8]⋯a[r]
当(r−l+1)%4=2(r-l+1) \%4=2(r−l+1)%4=2时,答案为a[l]⊕a[l+1]⊕a[l+4]⊕a[l+5]⋯a[r−1]⊕a[r]a[l]\oplus a[l+1] \oplus a[l+4] \oplus a[l+5] \cdots a[r-1] \oplus a[r]a[l]⊕a[l+1]⊕a[l+4]⊕a[l+5]⋯a[r−1]⊕a[r]
当(r−l+1)%4=3(r-l+1) \%4=3(r−l+1)%4=3时,答案为a[l+1]⊕a[l+5]⊕a[l+9]⋯a[r−1]a[l+1]\oplus a[l+5] \oplus a[l+9] \cdots a[r-1]a[l+1]⊕a[l+5]⊕a[l+9]⋯a[r−1]
因为有10610^6106组查询,所以还需要求一个间隔为444的前缀异或和,这样就可以实现O(1)O(1)O(1)查询
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <set>
#include <utility>
#include <sstream>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define inf 0x3f3f3f3f
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define lep(i,l,r) for(int i=l;i>=r;i--)
#define ms(arr) memset(arr,0,sizeof(arr))
//priority_queue<int,vector<int> ,greater<int> >q;
const int maxn = (int)1e5 + 5;
const ll mod = 1e9+7;
int arr[100100];
int sum[4][100100];
int main()
{#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);#endif//freopen("out.txt", "w", stdout);ios::sync_with_stdio(0),cin.tie(0);int t;scanf("%d",&t);while(t--) {int n;scanf("%d",&n);rep(i,1,n) {scanf("%d",&arr[i]);sum[0][i]=sum[1][i]=sum[2][i]=sum[3][i]=0;}sum[1][1]=arr[1];sum[2][2]=arr[2];sum[3][3]=arr[3];sum[0][4]=arr[4];rep(i,5,n) {sum[1][i]=sum[1][i-4]^arr[i];sum[2][i+1]=sum[2][i+1-4]^arr[i+1];sum[3][i+2]=sum[3][i+2-4]^arr[i+2];sum[0][i+3]=sum[0][i+3-4]^arr[i+3];}int q;scanf("%d",&q);rep(i,1,q) {int l,r;scanf("%d%d",&l,&r);int len=r-l+1,ans;if(len%4==0) printf("0\n");else if(len%4==1) {ans=sum[r%4][r]^sum[l%4][l]^arr[l];printf("%d\n",ans);}else if(len%4==2) {ans=sum[r%4][r]^sum[(l+1)%4][l+1]^arr[l+1];ans=ans^(sum[(r-1)%4][r-1]^sum[l%4][l]^arr[l]);printf("%d\n",ans);}else {ans=sum[(r-1)%4][r-1]^sum[(l+1)%4][l+1]^arr[l+1];printf("%d\n",ans);}}}return 0;
}