zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    细心也是一种态度
    EDM数据访问的三种方式
    如何快速提交网站备案 ICP备案
    c# winform 关于给静态全局变量赋值的问题
    c#DIY随机数类winform 2010
    手把手教你如何用IIS搭建手机WAP网站(图文)
    admin密码对应的MD5值,16位和32位,admin解密自己留着方便.
    C#实现MD5加密,winform c#2005
    最全的c#日期函数 winform
    如何解决因网站备案号没下来而网站被迫关闭的办法
  • 原文地址:https://www.cnblogs.com/tiberius/p/9261602.html
Copyright © 2011-2022 走看看