题目链接 
特别感谢 主机 
给定大小为n n n { a n } \{a_n\} { a n  } 
构造b b b b x , y = { a y , x = 0 b x − 1 , y ⊕ b x − 1 , y + 1 , x > 0   b_{x, y} = \begin{cases} a_y, & x=0 \\ b_{x-1,y} \oplus b_{x-1,y+1} , & x>0 \end{cases}~ b x , y  = { a y  , b x − 1 , y  ⊕ b x − 1 , y + 1  ,  x = 0 x > 0    x + y ⩽ n − 1 x+y \leqslant n-1 x + y ⩽ n − 1 ⊕ \oplus ⊕ 
有q q q ( x , y ) (x, y) ( x , y ) b x , y b_{x, y} b x , y  
(此方法几乎不需要任何知识储备,但思维难度较高) 
首先应考虑如何减小计算次数.
依异或运算的性质x ⊕ x = 0 x \oplus x=0 x ⊕ x = 0 
我们首先想到将b x , y b_{x, y} b x , y  b x , y b_{x, y} b x , y  b 0 , y ,   b 0 , y + 1 ,   … ,   b 0 , y + x b_{0, y},~b_{0, y+1},~\dots,~b_{0, y+x} b 0 , y  ,   b 0 , y + 1  ,   … ,   b 0 , y + x  在异或表达式中出现的次数  进行判断,如出现奇数次,就需要计算,如果是偶数次,那么就消掉了,不需要计算.
举个栗子,计算b 2 , 2 = b 1 , 2 ⊕ b 1 , 3 = b 0 , 2 ⊕ b 0 , 3 ⊕ b 0 , 3 ⊕ b 0 , 4 b_{2,2}=b_{1,2} \oplus b_{1,3}=b_{0,2} \oplus b_{0,3} \oplus b_{0,3} \oplus b_{0,4} b 2 , 2  = b 1 , 2  ⊕ b 1 , 3  = b 0 , 2  ⊕ b 0 , 3  ⊕ b 0 , 3  ⊕ b 0 , 4  b 0 , 2 ⊕ b 0 , 4 b_{0,2} \oplus b_{0,4} b 0 , 2  ⊕ b 0 , 4  b 0 , 3 b_{0,3} b 0 , 3  b 0 , 2 b_{0,2} b 0 , 2  b 0 , 4 b_{0,4} b 0 , 4  
如何判断出现的次数呢?
刚才的栗子中,b 0 , 2 , b 0 , 3 , b 0 , 4 b_{0,2},b_{0,3},b_{0,4} b 0 , 2  , b 0 , 3  , b 0 , 4  1 , 2 , 1 1,2,1 1 , 2 , 1 2 2 2 
能够证明,在b x , y b_{x, y} b x , y  b 0 , y ,   b 0 , y + 1 ,   … ,   b 0 , y + x b_{0, y},~b_{0, y+1},~\dots,~b_{0, y+x} b 0 , y  ,   b 0 , y + 1  ,   … ,   b 0 , y + x  x x x 杨辉三角中,哪些项是奇数,哪些是偶数 .
先打个表:
打表程序(最朴素的杨辉三角):
1 2 3 4 5 6 7 8 9 10 int  a[88 ][88 ] = { 0  };for  (int  i = 0 ; i < n; ++i) {    a[i][0 ] = a[i][i] = 1 ;     for  (int  j = 1 ; j < i; ++j) a[i][j] = a[i-1 ][j] ^ a[i-1 ][j-1 ]; } for  (int  i = 0 ; i < n; ++i) {    std::cout << '\n'  << i << ":\t" ;     for  (int  j = 0 ; j < 88  - i; ++j) std::cout << " " ;     for  (int  j = 0 ; j < i + 1 ; ++j) std::cout << a[i][j] << " " ; } 
我发现它的第2 i 2^i 2 i 2 i − 1 2^i-1 2 i − 1 2 i 2^i 2 i b x , y = b x − 2 i , y ⊕ b x − 2 i , y + 2 i b_{x,y}=b_{x-2^i,y} \oplus b_{x-2^i,y+2^i} b x , y  = b x − 2 i , y  ⊕ b x − 2 i , y + 2 i  
如x = 19 → 19 − 16 = 3 x = 3 → 3 − 2 = 1 x = 1 → 1 − 1 = 0 x = 0 x=19 \xrightarrow{19-16=3} x=3 \xrightarrow{3-2=1} x=1 \xrightarrow{1-1=0} x=0 x = 1 9 1 9 − 1 6 = 3  x = 3 3 − 2 = 1  x = 1 1 − 1 = 0  x = 0 
这样计算的项数会比较少……吗?每有一个二进制位为1 1 1 2 15 2^{15} 2 1 5 TLE \text{TLE} TLE 
一个自然的想法是不要全部化为x = 0 x=0 x = 0 N N N x < N x<N x < N 根号分治  的想法),但依旧TLE \text{TLE} TLE 
再次问这个问题:如何减小计算次数?
既然我们决定化到x < N x<N x < N 
借助你强大的观察力,发现,模二杨辉三角第x \boldsymbol x x x N \boldsymbol{\frac xN} N x  N − 1 \boldsymbol{N-1} N − 1 0 \boldsymbol0 0 N = 2 i \boldsymbol{N=2^i} N = 2 i  ).
没注意到也没关系,如果你的注意力足够……近视  的话,能发现上面那个图形是个 分形 .
分形是一种可以分成数个部分,且每一部分都是整体缩小后的形状的形态特征. 
有什么用?我们可以从图中「抽出」一个图形,比如,每隔4 4 4 4 4 4 x x x x 4 \frac x4 4 x  3 3 3 0 0 0 
1 1   1 1   0   1 1   1   1   1 1   0   0   0   1 1   1   0   0   1   1 1   0   1   0   1   0   1 1   1   1   1   1   1   1   1 1   0   0   0   0   0   0   0   1 \begin{array}{} {\color{green}1} \\ {\color{blue}1~1} \\ {\color{blue}1~0~1} \\ 1~1~1~1 \\ {\color{red}1}~0~0~0~{\color{red}1} \\ 1~1~0~0~1~1 \\ 1~0~1~0~1~0~1 \\ 1~1~1~1~1~1~1~1 \\ {\color{red}1}~0~0~0~{\color{red}0}~0~0~0~{\color{red}1} \\ \end{array} 1 1   1 1   0   1 1   1   1   1 1   0   0   0   1 1   1   0   0   1   1 1   0   1   0   1   0   1 1   1   1   1   1   1   1   1 1   0   0   0   0   0   0   0   1  
这样的递归就快很多了:如果x = N q x=Nq x = N q 0 0 0 0 0 0 q q q q q q 01 01 0 1 0 0 0 
如果带有余数x = N q + r x=Nq+r x = N q + r r r r N N N r r r 
前N N N 
1 2 3 4 5 6 7 const  int  maxN = 3e5  + 7 , N = 512 ;int  a[N][maxN];for  (int  j = 1 ; j < N; ++j) {    for  (int  i = 0 ; i < n - j; ++i) {         a[j][i] = a[j - 1 ][i] ^ a[j - 1 ][i + 1 ];     } } 
按上面的分析,N N N 2 2 2 maxN \sqrt{\text{maxN}} maxN  512 512 5 1 2 
预处理模二杨辉三角:
1 2 3 4 5 6 7 8 9 const  int  M = 587 ;int  b[M][M];b[0 ][0 ] = 1 ; for  (int  j = 1 ; j < M; ++j) {    b[j][0 ] = b[j][j] = 1 ;     for  (int  i = 1 ; i < j; ++i)         b[j][i] = b[j - 1 ][i] ^ b[j - 1 ][i - 1 ]; } 
因为计算x = N q + r x=Nq+r x = N q + r q q q q q q ⌈ x N ⌉ \lceil\frac{x}{N}\rceil ⌈ N x  ⌉ M = ⌈ x N ⌉ = 587 M=\lceil\frac{x}{N}\rceil=587 M = ⌈ N x  ⌉ = 5 8 7 
核心部分:
1 2 3 4 5 6 7 8 9 inline  int  solve (int  x, int  y)      int  q = x / N, r = x % N;     int  ans = 0 ;     for  (int  i = 0 ; i <= q; ++i) {          if  (b[q][i] == 1 )              ans ^= a[r][i * N + y];      }     return  ans; } 
时间复杂度Θ ( N n + M 2 + q M ) ≈ Θ ( n + q ) \Theta(Nn+M^2+qM)\approx\Theta(n+q) Θ ( N n + M 2 + q M ) ≈ Θ ( n + q ) 1778ms \text{1778ms} 1778ms 
AC code1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include  <cstdio>  #define  Code int main() { int T=1; #define  Codes int main() { int T=read(); #define  by while (T--) eachT(); #define  HTLDL return 0; #define  HappyHDUPKSAI } inline  long  long  read ()  char  st; long  long  x = 0 ; int  fu = 1 ; st = getchar (); while  (st > 57  || st < 48 ) { if  (st == 45 ) fu = -1 ; st = getchar (); }while  (st <= 57  && st >= 48 ) { x = (x << 3 ) + (x << 1 ) + st - 48 ; st = getchar (); }return  x * fu; }typedef  long  long  ll;const  int  maxN = 3e5  + 7 , N = 512 , M = 587 ;int  a[N][maxN], b[M][M];inline  int  solve (int  y, int  x)      int  q = x / N, r = x % N;     int  ans = 0 ;     for  (int  i = 0 ; i <= q; ++i) {         if  (b[q][i] == 1 )             ans ^= a[r][i * N + y];     }     return  ans; } void  eachT ()      int  n = read ();     for  (int  i = 0 ; i < n; ++i) a[0 ][i] = read ();     for  (int  j = 1 ; j < N; ++j) {         for  (int  i = 0 ; i < n - j; ++i)             a[j][i] = a[j - 1 ][i] ^ a[j - 1 ][i + 1 ];     }      b[0 ][0 ] = 1 ;     for  (int  j = 1 ; j < M; ++j) {         b[j][0 ] = b[j][j] = 1 ;         for  (int  i = 1 ; i < j; ++i)             b[j][i] = b[j - 1 ][i] ^ b[j - 1 ][i - 1 ];     }      int  q = read ();     while  (q--) printf ("%d\n" , solve (read (), read ())); } Code by HTLDL HappyHDUPKSAI