题解 AT4433 【[ARC103C] Tr/ee】
神仙构造orz。
其实本质上这种构造树形态的题目,只要熟悉不同形态的树的性质就不难做了吧?
首先显然的是
这种构造,如果强行定义的话,可能存在某种套路。思考这一种比较自然的构造方式:找到最大的连通块,让其成为
但是至少发现,连散点是个比较好的方式,而上一个方法欠缺的就是难以准确构造连通块。这就可以把思路引到「菊花」上。发现对于一个
形式化地讲,考虑设
显然这种构造方式能凑出所有
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std ;
const int N = 200010 ;
int n ;
int m ;
int top ;
int cnt ;
char s[N] ;
int sz[N] ;
int stk[N] ;
int main(){
cin >> (s + 1) ;
n = strlen(s + 1) ;
if (s[1] == '0') return puts("-1"), 0 ;
if (s[n] == '1') return puts("-1"), 0 ;
for (int i = 1 ; i < n ; ++ i)
if (s[i] != s[n - i]) return puts("-1"), 0 ;
/*
for (int i = 1 ; i < n ; ++ i)
if (s[i] == '1') stk[++ top] = i ;
stk[++ top] = n ; int k ; cnt = 0 ;
while (top) sz[++ cnt] = stk[top --] ;
for (int i = 1 ; i < cnt ; ++ i)
printf("%d %d\n", i, i + 1), sz[i] -= sz[i + 1] ;
k = cnt ;
for (int i = 1 ; i <= cnt ; ++ i)
for (int j = 1 ; j <= sz[i] ; ++ j)
printf("%d %d\n", i, ++ cnt) ;
*/
m = 1 ;
for (int i = 1 ; i < n ; ++ i){
cout << i + 1 << " " << m << endl ;
if (s[i] == '1') m = i + 1 ;
}
return 0 ;
}