[AGC068B] 01 Graph Construction
Genius_Star · · 题解
或许更好的阅读体验。
感觉挺脑电波的构造题,怎么场上被过穿了。
思路:
考虑初始构造
考虑给
-
若给
S, T 末尾都加上0 ,那么会连上p_1 与n + 1 ,然后p 前面删掉p_1 ,后面再加上一个n + 1 没有被匹配,欸,你发现p_1 与n + 1 连通性一致,于是本质上是将p_1, \cdots, p_k 换成p_2, \cdots, p_k, p_1 。 -
若给
S 末尾加1 ,T 末尾加0 ,相当于连边p_1 与n + 1 ,q_1 与n + 1 连边,即合并了p_1 与q_1 的连通块;然后把p_1, q_1 从p, q 中删掉。
相当于你可以将
于是对于
时间复杂度为
完整代码:
#include<bits/stdc++.h>
#define fi first
#define se second
#define lowbit(x) x & (-x)
#define popcnt(x) __builtin_popcountll(x)
typedef long long ll;
using namespace std;
const int N = 1e4 + 10;
inline ll read(){
ll x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-')
f = -1;
c = getchar();
}
while(c >= '0' && c <= '9'){
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return x * f;
}
inline void write(ll x){
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
int n, k, m;
int p[N], q[N], a[N], X[N];
vector<int> V[N];
char s[N], t[N];
inline void del(){
for(int i = 1; i < k; ++i)
p[i] = p[i + 1], q[i] = q[i + 1];
--k;
}
inline void left(){
p[k + 1] = p[1];
for(int i = 1; i <= k; ++i)
p[i] = p[i + 1];
}
int main(){
n = read();
for(int i = 1; i <= n; ++i){
a[i] = read();
V[a[i]].push_back(i);
}
for(int i = 1; i <= n; ++i)
for(int j = 0; j < (int)V[i].size(); ++j)
X[V[i][j]] = V[i][(j + 1) % V[i].size()];
for(int i = 1; i <= n; ++i)
p[i] = q[i] = i, s[i] = '0', t[i] = '1';
k = m = n;
while(k){
if(X[q[1]] == p[1]){
s[++m] = '1';
t[m] = '0';
del();
}
else{
s[++m] = '0';
t[m] = '0';
left();
}
}
write(m);
putchar('\n');
printf("%s\n%s\n", s + 1, t + 1);
return 0;
}