#include <iostream>
using namespace std;
typedef long long LL;
int main()
{
LL t;
cin >> t;
LL n;
for (int i = 0; i < t; i++){
cin >> n;
LL yu = n % 4; //找规律,找到问题以4为循环规律节点
if (yu == 0) cout << n << endl; //四个情况
else if (yu == 1) cout << 0 << endl;
else if (yu == 2) cout << n + 1 << endl;
else cout << 1 << endl;
}
return 0;
}
咳咳,本人第一次写博客,有问题请指正哈😁
下面,我们来分析这道题吧!
当你看到了图和最短路时,是否脑子一热:我会,djikstra和spfa嘛。但是定睛一看,完全图和 n (1≤n≤2×10^9) 显然,这不是搜索题。所以,这题没办法套用模板,找规律吧!
咋找呢?
我们先读题,再看示例解析(我相信看这篇文的大部分人是没有明白题要干嘛的)
对于第二组测试数据,从 1 号点出发到 2 号点只能走 1→2 这条边,因此 d2 = 3,而又因为 d1= 0,因此输出的 S=d1⊕d2=0⊕3=3。
嘛,发现没? 1 -> 1 是有路的! 所以:
S = 所有d的异或 = (1⊕1)⊕(1⊕2)⊕(1⊕3)···(1⊕n)= (1⊕1···1⊕1)⊕(1⊕···i···⊕n)<n个1,i属于n>
所以,我们只需要知道前面(1⊕1···1⊕1)是多少,再和后面(1⊕···i···⊕n)异或就行了!
我们知道,2m+1个 1 的异或为 1, 2m个1的异或为0,所以,前面解决!那后面咋办?
有些同学可能会想:用数组?但是数组太大了!而且访问没有规律,这个不行!有没有时间空间都是O(1)的方案呢?有!我们看这段代码:
#include<iostream>
using namespace std;
int main() {
int sum = 1;
for (int i = 2; i <= 20; i++) { //输出前20个找早规律
sum ^= i;
cout << sum <<" " << i << endl; // 异或 n
}
return 0;
}
3 2 0 3 4 4 1 5 7 6 0 7 8 8 1 9 11 10 0 11 12 12 1 13 15 14 0 15 16 16 1 17 19 18 0 19 20 20
发现没?当 n%4 = i, i =1 -> result = 1, i = 2 -> result = n + 1 , i = 3 -> result = 0, i = 0 -> result = n ! 那么,规律就出来啦!只需要条件判断就行了!
AC代码放在开头了,谢谢!

京公网安备 11010502036488号