CodeForces 909F

题意略。

思路:

第一问:

递归地来写,找对称,发现关于(1<<y) - 1和(1<<y)对称的数字做 & 结果为0。

第二问:

6,7特殊考虑。循环左移(1<<y) ~ (1<<(y + 1) - 1),可以保证这个区间内的值与下标做 & 结果不为0。然而如果在这个段内只有1<<y这一个数,那么

我们无法循环左移,此时要特判为NO。

详见代码:

#include<bits/stdc++.h>
#define maxn 50
#define maxn2 100005
using namespace std;

int one[maxn],tail;
int ans1[maxn2],ans2[maxn2];
int six[] = {3,6,2,5,1,4};
int seven[] = {7,6,2,5,1,4,3};

void init(){
    one[0] = 0;
    tail += 1;
    for(int i = 1;(1<<i) - 1 <= 1000000;++i){
        one[i] = (1<<i) - 1;
        tail += 1;
    }
}
int cnt1(int x){
    int ret = 0;
    while(x){
        x = x & (x - 1);
        ++ret;
    }
    return ret;
}
void construct(int x){
    if(x <= 0) return;
    int pos = lower_bound(one,one + tail,x) - one - 1;
    int mid = one[pos] + 1;
    for(int i = mid;i <= x;++i) swap(ans2[i],ans2[mid - (i - mid) - 1]); 
    x = mid - (x - mid) - 1 - 1;
    construct(x);
}

int main(){
    init();
    int n;
    scanf("%d",&n);
    if(n & 1) printf("NO\n");
    else{
        printf("YES\n");
        for(int i = 1;i <= n;++i) ans2[i] = i;
        construct(n);
        printf("%d",ans2[1]);
        for(int i = 2;i <= n;++i) printf(" %d",ans2[i]);
        printf("\n");
    }
    
    if(n <= 5 || cnt1(n) == 1) printf("NO\n");
    else if(n == 6){
        printf("YES\n");
        printf("%d",six[0]);
        for(int i = 1;i < 6;++i) printf(" %d",six[i]);
        printf("\n");
    }
    else if(n == 7){
        printf("YES\n");
        printf("%d",seven[0]);
        for(int i = 1;i < 7;++i) printf(" %d",seven[i]);
        printf("\n");
    }
    else{
        printf("YES\n");
        for(int i = 1;i <= 7;++i) ans1[i] = seven[i - 1];
        int lft = 8,rht = min((lft<<1) - 1,n);
        while(lft < n){
            for(int i = lft;i <= rht;++i){
                if(i < rht) ans1[i] = i + 1;
                else ans1[i] = lft;
            }
            lft = lft<<1;
            rht = min((lft<<1) - 1,n);
        }
        printf("%d",ans1[1]);
        for(int i = 2;i <= n;++i) printf(" %d",ans1[i]);
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/tiberius/p/9261602.html