Given a sequence of n n n numbers a 1 , a 2 , ⋯   , a n a_1, a_2,\cdots, a_n a1,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
1
1
1:
t
(
1
≤
t
≤
20
)
t (1 \le t \le 20)
t(1≤t≤20).
For each test case:
Line 1 1 1: n ( 1 ≤ n ≤ 100000 ) n (1 \le n \le 100000) n(1≤n≤100000).
Line 2 2 2: n n n numbers a 1 , a 2 , ⋯   , a n ( 1 ≤ a i ≤ 1 0 9 ) a_1, a_2, \cdots, a_n (1 \le a_i \le 10^9) a1,a2,⋯,an(1≤ai≤109)
Line 3 3 3: 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 2 2 2 numbers i , j i, j i,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 n n n and q ≤ 1 0 6 q \le 10^6 q≤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_JUDGE
freopen("in.txt", "r", stdin);
#endif
freopen("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时,答案为
0
0
0;
当
(
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]
因为有
1
0
6
10^6
106组查询,所以还需要求一个间隔为
4
4
4的前缀异或和,这样就可以实现
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_JUDGE
freopen("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;
}