A Bit Similar【CF 1469E】【unordered_map+bitset】

题目链接

  有一个长度为N的01串,现在我们要找一个长度为K的字典序最下的01串,使得将这个长度K的串从N串的头滑到N-K+1位,至少有一位是有相同0或者1的。

  于是,我们可以将问题看成:找一个最大的01串,使得它不与任意一个N长串的子串完全相同,那么,这个串的反码不就是我们所需要的答案了吗?因为保证了不完全相同,所以它的反转过后一定存在相同的位置。

  于是,我们又可以发现,220是大于1e6的,所以最多就找220就可以找到答案了,所以当K>20的时候,我们让“>20”的部分为0,就可以了。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <string>
 5 #include <cstring>
 6 #include <algorithm>
 7 #include <limits>
 8 #include <vector>
 9 #include <stack>
10 #include <queue>
11 #include <set>
12 #include <map>
13 #include <bitset>
14 #include <unordered_map>
15 #include <unordered_set>
16 #define lowbit(x) ( x&(-x) )
17 #define pi 3.141592653589793
18 #define e 2.718281828459045
19 #define INF 0x3f3f3f3f
20 #define HalF (l + r)>>1
21 #define lsn rt<<1
22 #define rsn rt<<1|1
23 #define Lson lsn, l, mid
24 #define Rson rsn, mid+1, r
25 #define QL Lson, ql, qr
26 #define QR Rson, ql, qr
27 #define myself rt, l, r
28 #define pii pair<int, int>
29 #define MP(a, b) make_pair(a, b)
30 using namespace std;
31 typedef unsigned long long ull;
32 typedef unsigned int uit;
33 typedef long long ll;
34 const int maxN = 1e6 + 7;
35 int N, K, kk;
36 char b[maxN];
37 int dig[maxN];
38 unordered_map<bitset<22>, bool> mp;
39 int main()
40 {
41     int T; scanf("%d", &T);
42     while(T --)
43     {
44         scanf("%d%d", &N, &K);
45         scanf("%s", b + 1);
46         for(int i = 1; i <= N; i ++) dig[i] = b[i] - '0';
47         kk = min(K, 22);
48         mp.clear();
49         bitset<22> tmp;
50         int pre = 0;
51         int len = K - kk;
52         for(int i = 1; i <= len; i ++)
53         {
54             if(!dig[i]) pre ++;
55         }
56         for(int i = K, j = 0; i >= K - kk + 1; i --, j ++)
57         {
58             if(dig[i]) tmp.set(j);
59         }
60         if(!pre) mp[tmp] = true;
61         for(int i = K + 1; i <= N; i ++)
62         {
63             if(!dig[i - K]) pre --;
64             if(!dig[i - kk]) pre ++;
65             tmp.reset(kk - 1);
66             tmp <<= 1;
67             if(dig[i]) tmp.set(0);
68             if(!pre) mp[tmp] = true;
69         }
70         tmp.reset();
71         for(int i = 0; i < kk; i ++) tmp.set(i);
72         bool ok = false;
73         if(!mp.count(tmp)) ok = true;
74         while(tmp.any() && !ok)
75         {
76             for(int i = 0; i < kk; i ++)
77             {
78                 if(tmp.test(i))
79                 {
80                     tmp.reset(i);
81                     for(int j = 0; j < i; j++) tmp.set(j);
82                     break;
83                 }
84             }
85             if(!mp.count(tmp)) ok = true;
86         }
87         if(!ok) printf("NO
");
88         else
89         {
90             printf("YES
");
91             for(int i = K - 1; i >= kk; i --) printf("0");
92             for(int i = kk - 1; i >= 0; i --) printf("%d", !tmp.test(i));
93             printf("
");
94         }
95     }
96     return 0;
97 }
原文地址:https://www.cnblogs.com/WuliWuliiii/p/14206579.html