• 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
    ");
        else{
            printf("YES
    ");
            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("
    ");
        }
        
        if(n <= 5 || cnt1(n) == 1) printf("NO
    ");
        else if(n == 6){
            printf("YES
    ");
            printf("%d",six[0]);
            for(int i = 1;i < 6;++i) printf(" %d",six[i]);
            printf("
    ");
        }
        else if(n == 7){
            printf("YES
    ");
            printf("%d",seven[0]);
            for(int i = 1;i < 7;++i) printf(" %d",seven[i]);
            printf("
    ");
        }
        else{
            printf("YES
    ");
            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("
    ");
        }
        return 0;
    }
  • 相关阅读:
    Linux搭建maven私服
    eclipse提交项目到GitHub
    eclipse安装sts插件
    idea配置jdk
    C语言之链表————(转载)
    链表(创建,插入,删除和打印输出(转载)
    C语言之链表
    ARM 之LCD和LCD控制器
    ARM的两种启动方式 (NAND FLASH. NOR FLASH)
    ARM 汇编器对C的扩展
  • 原文地址:https://www.cnblogs.com/tiberius/p/9261602.html
Copyright © 2020-2023  润新知