P3908 数列之异或
- 题意:输入n,输出数列{1, 2, 3, ... , n}异或的结果
如何O(1)做?
(1)、
我们知道如果某个数n为奇数,那么n-1为偶数,并且n^(n-1)==1【不知道自己写一下就知道了,因为非负整数是从0开始的】
所以对于这道题来说,如果n为奇数,那么我们只需要数一下有多少个奇数即可
如果n为偶数,那么就强制n=n-1为奇数,同上解决,最后再异或一个n+1即可
ll n, ans; n = read();
bool even = false;
if(!(n & 1)) --n, even = true;
if((n + 1) >> 1 & 1) //奇数个1
ans = 1;
else
ans = 0;
if(even) cout << (ans ^ (n + 1));
else cout << ans;
(2)、
dl总结出的规律,证明就不给了,很D区
ll n; n = read();
switch(n % 4)
{
case 0: cout << n << '\n'; break;
case 1: cout << "1\n"; break;
case 2: cout << n + 1 << '\n'; break;
case 3: cout << "0\n"; break;
}
其实两者很相像的!第一种很容易理解,可以由第一种打表看一下,第二种的规律总结也很显然。【果然还是数学归纳法最香了~
整代码
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
inline ll read()
{
ll x = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -f; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x * f;
}
const int maxN = 100005;
int main()
{
// ll n, ans; n = read();
// bool even = false;
// if(!(n & 1)) --n, even = true;
// if((n + 1) >> 1 & 1) //奇数个1
// ans = 1;
// else
// ans = 0;
// if(even) cout << (ans ^ (n + 1));
// else cout << ans;
ll n; n = read();
switch(n % 4)
{
case 0: cout << n << '\n'; break;
case 1: cout << "1\n"; break;
case 2: cout << n + 1 << '\n'; break;
case 3: cout << "0\n"; break;
}
return 0;
}