CF - 1110 C Meaningless Operations

题目传送门

题解:

首先根据观察,很容易发的是:

  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\n", ans[n]);
    }
}
int main(){
    init();
    while(~scanf("%d", &q)){
        Ac();
    }
    return 0;
}
View Code

  

猜你喜欢

转载自www.cnblogs.com/MingSD/p/10356134.html