题解:
首先根据观察,很容易发的是:
x != (1<<k) - 1 时候 答案就是, 将x二进制下再最高位后的0都变成1。
然后就是考虑 x == (1<<k) - 1的时候
同样根据观察可以得到 b ^ x = x - b, b&x = b
所以就是将x拆成2个数, 然后这2个数的gcd最大。
我们就最后找x的因子。 如 x = b * c
那么们就可以把2个数分成 c , (b-1) * c,gcd 为 c。
或者 b , b * (c-1) gcd为b
代码:
/* code by: zstu wxk time: 2019/02/08 */ #include<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e5 + 100; int q, n; int ans[(1<<25) + 100]; int _pow[N]; int cal(int x){ int ret = 1; for(int i = 2; i * i <= x; ++i){ if(x%i == 0){ ret = max({ret, i, x/i}); } } return ret; } void init(){ ans[2] = 3; ans[3] = 1; int t = 8; for(int i = 3; i <= 25; ++i){ int m = t - 1, z = t - 2; while(!ans[z]){ ans[z] = m; --z; } ans[m] = cal(m); t *= 2; } } void Ac(){ for(int i = 1; i <= q; ++i){ scanf("%d", &n); printf("%d ", ans[n]); } } int main(){ init(); while(~scanf("%d", &q)){ Ac(); } return 0; }