Codeforces Round #455 (Div. 2)F. AND-permutations[bitmasks]

题目:http://codeforces.com/contest/909/problem/F

题意:给出数字n,找出两种序列,要求下标和数字不同并且与值为0(不为0)

分析:一个只在最高位有1的数字n(例如10000B),n+i-1和n-i每一位正好相反(i=1,2,3……),与值为0.则如果n为偶数,可以构造出第一种序列,从n开始,以最高位为1且小于n的数字为对称轴组合。例如n=10,找到的对称轴为8,第一次处理完10-5、9-6、8-7,不断更新上界,第二次再从6开始类似的处理。只要是偶数一定可以找到答案。

与值不为1,若最大值n为100000B这样的数字,只有最高位有1而且它为最大值,怎么都不可能有数字和他与值为1且和他不同,则输出NO。剩余情况可以利用lowbit函数找到n的最末位1,从n到这个数字之间的数字一定有这一位公共的1(例如100100B,找到的为100100B+100B=101000B),只需要保证他们不和下标相等即可,不断更新下界,小数字会出现问题,特判小于8的情况。

代码:

 1 #define _CRT_SECURE_NO_DEPRECATE
 2 #pragma comment(linker, "/STACK:102400000,102400000")
 3 #include<iostream>  
 4 #include<cstdio>  
 5 #include<fstream>  
 6 #include<iomanip>
 7 #include<algorithm>  
 8 #include<cmath>  
 9 #include<deque>  
10 #include<vector>
11 #include<bitset>
12 #include<queue>  
13 #include<string>  
14 #include<cstring>  
15 #include<map>  
16 #include<stack>  
17 #include<set>
18 #include<functional>
19 #define pii pair<int, int>
20 #define mod 1000000007
21 #define mp make_pair
22 #define pi acos(-1)
23 #define eps 0.00000001
24 #define mst(a,i) memset(a,i,sizeof(a))
25 #define all(n) n.begin(),n.end()
26 #define lson(x) ((x<<1))  
27 #define rson(x) ((x<<1)|1) 
28 #define inf 0x3f3f3f3f
29 typedef long long ll;
30 typedef unsigned long long ull;
31 using namespace std;
32 const int maxn = 1e5 + 5;
33 int a[maxn];
34 int b[maxn];
35 
36 void getans(int t)
37 {
38     if (t == 0)return;
39     int temp = 1;
40     while (temp <= t)temp <<= 1;
41     temp >>= 1;
42     int cnt = t - temp + 1;
43     for (int i = 1; i <= cnt; ++i)
44     {
45         a[temp + i - 1] = temp - i;
46         a[temp - i] = temp + i - 1;
47     }
48     getans(temp - cnt - 1);
49 }
50 inline int lowbit(int t)
51 {
52     return t&(-t);
53 }
54 int main()
55 {
56     ios::sync_with_stdio(false);
57     cin.tie(0); cout.tie(0);
58     int i, j, k, m, n;
59     cin >> n;
60     if (n & 1)cout << "NO" << endl;
61     else
62     {
63         cout << "YES" << endl;
64         getans(n);
65         for (int i = 1; i <= n; ++i)cout << a[i] << " ";
66         cout << endl;
67     }
68     double ta = log2(n);
69     int tb = ta;
70     if (n < 6 || (n >= 8 && tb == ta))cout << "NO" << endl;
71     else
72     {
73         cout << "YES" << endl;
74         if (n == 6)cout << "3 6 2 5 1 4" << endl;
75         else
76         {
77             b[1] = 5, b[5] = 1, b[4] = 6, b[6] = 4, b[2] = 3, b[3] = 7, b[7] = 2;
78             int ed = 8;
79             for (int i = 8; i <= n; i = ed)
80             {
81                 ed += lowbit(i);
82                 ed = min(ed, n + 1);
83                 for (int j = i; j < ed - 1; ++j)b[j] = j + 1;
84                 b[ed - 1] = i;
85             }
86             for (int i = 1; i <= n; ++i)cout << b[i] << " ";
87             cout << endl;
88         }
89     }
90     return 0;
91 }

 

posted @ 2017-12-28 17:59  Meternal  阅读(466)  评论(0编辑  收藏  举报