codeforces1469 E. A Bit Similar

E. A Bit Similar

Code copy of this problem solution

Find a string of length k such that in the substring of s length k, at least one bit of the answer string is the same for all substrings . That is, if all substrings of length k of s are inverted bitwise, then the answer string cannot match these inverse strings.

Now the question is transformed into finding an answer string (the smallest lexicographical order), which cannot be combined with n − k + 1 n-k+1nk+1 string match.

For binary bits, since n − k + 1 <2 20 n-k+1<2^{20}nk+1<22 0 , that is, we need only 20 will be able to find through a string and those are different strings, so you can directly behind the violence enumerate 20 (k-20 bits are filled 0)

For finding one that does not correspond to n − k + 1 n-k+1nk+1 For matching strings, you can also hash them and record them with map. The answer is still enumeration,but it feels a bit troublesome to write, so I didn’t write it (not very good at writing)

Here is a very clever way, if n − k + 1 n-k+1nk+The frontk − 20 k-20 ina stringk2 0 position is present 1 do not control, because we enumerate the answers string in front ofk - 20 k-20k2 0 bits are 0, then an array can be recorded those things occurred (binary conversion)

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<bitset>
#include<random>
#include<bitset>
#include<string>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,int> pli;
typedef pair<int,int> pii;
const ll mod=1e9+7;
const int N=1000010;
bool ban[N];
int pre[N];
int main()
{
    
    
    IO;
    int T=1;
    cin>>T;
    while(T--)
    {
    
    
        int n,k;string s;
        cin>>n>>k>>s;
        int m=0;
        while(m<k&&(1<<m)<=n) m++;
        for(int i=0;i<=n&&i<(1<<m);i++) ban[i]=0;
        
        for(int i=0;i<n;i++) pre[i+1]=pre[i]+(int)(s[i]=='0');
        for(int i=0;i+k-1<n;i++)
        {
    
    
            if(pre[i]!=pre[i+k-m]) continue;
            int mask=0;
            for(int j=0;j<m;j++)
                if(s[i+k-1-j]=='0')
                    mask^=1<<j;
            if(mask<=n) ban[mask]=1;
        }
        int ans=0;
        while(ans<(1<<m)&&ban[ans]) ans++;
        if(ans==(1<<m)) cout<<"NO\n";
        else
        {
    
    
            cout<<"YES\n";
            for(int i=0;i<k-m;i++) cout<<0;
            for(int i=m-1;i>=0;i--) cout<<(int)((ans>>i)&1);
            cout<<'\n';
        }
    }
    return 0;
}

Summary: For at least one consideration of tolerance and exclusion transformation,
please do it~

Guess you like

Origin blog.csdn.net/Fighting_Peter/article/details/113099794