Codeforces1469E A Bit Similar

题目链接

至少要有一位相等,这样就会很复杂,可以反过来,全部不一样,好像就简单了不少

然后就可以预处理出来N/K个不能作为答案的长度为K的串
Hash一下
所以最多就N/K种

从0开始枚举就行了

#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <cstring>
#include <map>
using namespace std;

#define MAXN 10000006
#define HASH ((unsigned long long)100000000000000003)

map <unsigned long long , bool > mp;

char str[MAXN];
int ans[MAXN],top = 0;
unsigned long long Hash_Table[MAXN];

int main() {
	
	Hash_Table[0] = 1;
	for(int i=1;i<MAXN;++i) Hash_Table[i] = Hash_Table[i-1] * HASH;

	int T; cin >> T;
	while(T--) {

		int N,K; cin >> N >> K >> str;
		int str_len = strlen(str);

		for(int i=0;i<str_len;++i) str[i] = str[i]=='1' ? '0' : '1';

		unsigned long long H = 0; 
		int pos = 0; while(pos<K) H = H*HASH + (str[pos++]-'0');

		mp.clear(); mp[H] = true;
		for(int i=0;pos<str_len;++i) {
			H = ( H - Hash_Table[K-1]*((unsigned long long)(str[i]-'0')) )*HASH + (str[pos++]-'0');
			mp[H] = true;
		}

		H = 0;
		ans[top = 1] = 0; bool flag = false;
		for(int i=1;i<=N+1&&top<=K;++i) {
			if(!mp[H]) {
				flag = true; break;
			}
			if(!ans[1]) ans[1] = 1;
			else {
				int j = 1;  ans[j] ++;
				while(ans[j]==2&&j<=top) {
					ans[j] = 0; ans[j+1] ++; j++;
					if(j>top) {
						ans[++top] = 1; break;
					}
				}
			}
			
			H = 0;
			for(int j=1;j<=top;++j) 
				if(ans[j]) H += Hash_Table[j-1];
		}

		if(flag) {
			cout << "YES\n";
			for(int i=K;i>top;--i) cout << '0';
			for(int i=top;i>=1;--i) cout << ans[i];
			cout << '\n';
		}
		else cout << "NO\n";
	}

	return 0;
}
posted @ 2021-11-13 23:06  Neworld1111  阅读(23)  评论(0编辑  收藏  举报