思路:第一眼看过去以为是约瑟夫环,看了看约瑟夫环的解,感觉题目给出的数据范围过大,约瑟夫环肯定解决不了。既然数据很大,而且隔一个人淘汰,那第一波将会把全部的偶数淘汰,之后再逐步淘汰奇数,于是想到会不会是一个找规律的题。
我们计算出前10个数据对应的结果如下:
输入 | 输出 | 输入 | 输出 |
---|---|---|---|
1 | 1 | 10 | 5 |
2 | 1 | 11 | 7 |
3 | 3 | 12 | 9 |
4 | 1 | 13 | 11 |
5 | 3 | 14 | 13 |
6 | 5 | 15 | 15 |
7 | 7 | 16 | 1 |
8 | 1 | 17 | 3 |
9 | 3 | 18 | 5 |
我们可以很明显的看出来:
1.对于一个
2
n
2^n
2n这样的数字(比如1,2,4,8)输入恒为1
2.对于一个
2
n
−
1
2^n-1
2n−1这样的数字(比如3,7,15)输出就是他本身,即
2
n
−
1
2^n-1
2n−1
3.对于
2
n
−
1
−
2
n
2^{n-1}-2^n
2n−1−2n之间的数,呈现首项为1,公差为2的等比数列,求出
2
n
2^n
2n再计算出来就行了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<list>
#include<cmath>
#include<algorithm>
#include<fstream>
#include<sstream>
#include<time.h>
#define lson node<<1,st,mid
#define rson node<<1|1,mid+1,ed
#define mem(a,x) memset(a,x,sizeof(a))
#define me(a) memset(a,0,sizeof(a))
#define IOS ios::sync_with_stdio(false)
#define lowbit(x) x&(-x)
#define up(i,x,y) for(long long i=x;i<y;i++)
#define down(i,x,y) for(long long i=x;i>=y;i--)
typedef long long ll;
const ll mod=1e9+7;
const ll INF=0x3f3f3f3f;
const int maxn=1e5+5;
const double pi = acos(-1.0);
const int N=1e3+5;
using namespace std;
bool pd(ll n){
if(n&(n-1)==0) return true;
else return false;
}//判断一个数是不是2的n次方
ll qpow(ll a, ll n)//快速幂(因为左移符号好像有点问题,所以用了快速幂)
{
if (n == 0)
return 1;
else if (n % 2 == 1)
return qpow(a, n - 1) * a;
else
{
ll temp = qpow(a, n / 2);
return temp * temp;
}
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
ll n;
cin>>n;
if(pd(n)) cout<<"1"<<endl;
else{
if(pd(n+1)) cout<<n<<endl;
else{
ll ans=0;
ll k = n;
while(k){
ans += 1;
k/=2;
}
// cout<<ans<<endl;
ll x = qpow(2,ans);
// cout<<x<<endl;
ll res=x-1-(x-1-n)*2;
cout<<res<<endl;
}
}
}