solution-contest2.28(div2)A

典但是好的构造题。(除了在卡空间和输出格式这两点上。)

观察一下发现每一个区间的答案只和其中的 0、1 数量奇偶有关。考虑当前区间推向下一个区间答案是怎么变化的,发现之和 ii+ki \oplus i + k 有关。首先,如果 2n2 \nmid n 那么显然无解。不然我们考虑构造出所有 iii+ki+k 不相等那么就全对了。 考虑经典结论,ii 跳到 (i+k)modn(i+k) \mod n 一定会形成若干个长度为 gcd(n,k)\gcd(n,k) 的环。如果环长为奇数(特殊性质)那直接染就完了。否则手玩一下,感觉让一个环最开始两个数重是很优的,要是这样然还不行,那就真无解了。

#include<bits/stdc++.h>
using namespace std;
const long long inf = 1e18;
const int mininf = 1e9 + 7;
#define pb emplace_back
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void write(int x){if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0');}
#define put() putchar(' ')
#define endl puts("")
const int MAX = 8488609;

bool a[MAX];

void solve(){
	 int n = read(), k = read();
	 if(n % 2)	puts("-30"), exit(0);
	 int pre = 0;
	 bool fl = 0;
	 for(int i = 0; i < __gcd(n, k); i++){
 		int now = i;
 		bool cur = 1;
 		while(1){
 			a[now] = cur;
 			int to = (now + k) % n;
 			if(to == i){
 				if(a[to] == (cur ^ 1)){
 					break;
 				}else{
 					fl = 1;
 					if(pre <= 0){
 						pre++;
 						break;
 					}else{
 						pre--;
 						a[to] ^= 1;
 						break;
 					}
 				}
 				if(a[to] != (cur ^ 1)){ 
 					puts("-30");
 					return ;
 				}
 				break; 
 			}else{
 				now = to;
 				cur ^= 1;
 			}
 		}
	 }
	if(n == k or (n % 4 != 0 and k % 2 == 0)){
		puts("-30");
		return ;
	}
		
 	 for(int i = 0; i < n; i++)	write(a[i]);
 	endl;
	
}

signed main(){
	int t = 1;
	while(t--)	solve();
	return 0;
}