解題思路是:
Q=q1^q2.......^qn = p1^p2......^pn^((1%1)^....(1%n))^((2%1)^......(2%n))^....
故Q的求解過程分成兩部分
第一部分是求p1^p2......^pn
第二部分是求((1%1)^....(1%n))^((2%1)^......(2%n))^....
將其化成矩形的形式
1%1 1%2 ........... 1%n
2%1 2%2 ............ 2%n
.....................................
n%1 n%2 ............. n%n
當i小於除數時,即 i%j = i (i<j)
故該矩形的上對角線變成
1%1 1 ........... 1 (n-1)個1
2%1 2%2 ............ 2 (n-2)個2
..................................... ........
(n-1)%1................ n-1
n%1 n%2 ............. n%n 0個n
注意偶數個相同的元素異或結果為0,奇數個相同元素異或結果為本身,0與其他元素異或結果為該元素
故對於矩形上三角 只需要考慮(n-i)的奇偶性 故這部分程式碼簡化為
if(n-i是偶數) res^=i;
現在考慮矩形下三角,將下三角取餘數的
0
0 0
0 1 0
. 0 1 ..
. 1 2
. . 0 ...................
. . .
0 .........................................
根據規律
第一列為0迴圈變化
第二列為0~1迴圈變化
第i列為 0 ~i-1 迴圈變化
...........
第i列元素個數為n-i+1
得到每列的迴圈個數及剩餘的個數
判斷迴圈個數的奇偶,注意偶數個相同的元素異或結果為0,奇數個相同元素異或結果為1,0與任何元素異或結果為該元素
然後將剩餘的個數異或即可
#include <iostream> #include <vector> using namespace std; int main(){ int n,res = 0,p; cin>>n; vector<int> table(n+1,0); for(int i = 1 ; i <= n; ++ i){ cin >> p; res^=p; //針對p1^p2......^pn if((n-i)%2) res^=i; //針對上三角 table[i]^=table[i-1]^i; //打表 } int a = 1; for(int i = 0 ; i < n ; ++ i){ //針對下三角 int num = (n-i)/a, leave = (n-i)%a; if(num%2) res^=table[a-1]; if(leave) res^=table[leave-1]; a++; } cout<<res<<endl; }