1. 程式人生 > 實用技巧 >A Bit Similar【CF 1469E】【unordered_map+bitset】

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\n"); 88 else 89 { 90 printf("YES\n"); 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("\n"); 94 } 95 } 96 return 0; 97 }