QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#821123#3033. Harry Potter and the Palindromic Radiusucup-team2172#100 ✓1981ms32696kbC++232.5kb2024-12-19 13:32:152024-12-19 13:32:15

Judging History

This is the latest submission verdict.

  • [2024-12-19 13:32:15]
  • Judged
  • Verdict: 100
  • Time: 1981ms
  • Memory: 32696kb
  • [2024-12-19 13:32:15]
  • Submitted

answer

#include <bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
    int ch = 0, f = 0; x = 0;
    for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
    for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
    if(f) x = -x;
}
const int N = 2000005;
char str[N];
int r[N], fa[N], ans[N], n;
inline int ask(int x){ return x == fa[x] ? x : fa[x] = ask(fa[x]); }
inline void merge(int x, int y){
    int p = ask(x), q = ask(y);
    if(p != q) fa[p] = q;
}
inline int unite(int a, int b, int o){
    assert(1 <= a && a <= n && 1 <= b && b <= n);
    if(o == 0){
        merge(2 * a, 2 * b);
        merge(2 * a + 1, 2 * b + 1);
    }
    else{
        merge(2 * a + 1, 2 * b);
        merge(2 * a, 2 * b + 1);
    }
    if(ask(2 * a) == ask(2 * a + 1)) return 1;
    if(ask(2 * b) == ask(2 * b + 1)) return 1;
    return 0;
}
inline void dfs(int i){
    if(i == n + 1) return (void) (puts(str + 1));
    int p = ask(2 * i), q = ask(2 * i + 1);
    if(ans[p] || ans[q]){
        assert(ans[p] + ans[q] == 1);
        if(ans[p]) str[i] = '0';
        else str[i] = '1';
        dfs(i + 1);
    }
    else{
        ans[p] = 1;
        str[i] = '0';
        dfs(i + 1);
        ans[p] = 0;
        ans[q] = 1;
        str[i] = '1';
        dfs(i + 1);
        ans[q] = 0;
    }
}
inline void solve(){
    read(n);
    for(int i = 1; i <= n; i++) read(r[i]);
    for(int i = 2; i <= 2 * n + 1; i++) fa[i] = i;
    for(int i = 1; i <= n; i++) 
        if(i - r[i] < 1 || i + r[i] > n) return (void) (puts("0"));
    for(int i = 1, mx = 0, p = 0, flag = 0; i <= n; i++){
        int s = mx > i ? min(mx - i, r[2 * p - i]) : 0;
        for(int j = s + 1; j <= r[i]; j++) 
            flag |= unite(i - j, i + j, 0);
        if(i - r[i] - 1 >= 1 && i + r[i] + 1 <= n)
            flag |= unite(i - r[i] - 1, i + r[i] + 1, 1);
        if(flag) return (void) (puts("0"));
        if(i + r[i] > mx) mx = i + r[i], p = i;
    } 
    for(int i = 1; i <= n; i++) 
        if(ask(2 * i) == ask(2 * i + 1)) return (void) (puts("0"));
    int cnt = 0;
    for(int i = 2; i <= 2 * n + 1; i++) if(i == ask(i)) cnt++;
    assert(cnt % 2 == 0 && (1 << (cnt / 2)) <= 100);
    printf("%d\n", (1 << (cnt / 2)));
    str[n+1] = '\0';
    for(int i = 2; i <= 2 * n + 1; i++) ans[i] = 0;
    dfs(1);
}
int main(){
    int T; read(T); while(T--) solve();
    return 0;
}

详细


Pretests


Final Tests

Test #1:

score: 100
Accepted
time: 1981ms
memory: 32696kb

input:

131112
2
0 0
2
0 1
2
0 0
2
1 0
2
0 0
2
0 1
2
0 0
2
0 1
3
0 1 0
3
0 1 1
3
0 0 0
3
0 1 0
3
0 1 0
3
0 2 0
3
0 0 0
3
1 0 0
3
0 0 0
3
1 0 0
3
0 1 0
3
0 2 0
3
0 0 0
3
0 0 1
3
0 1 0
3
0 2 0
4
0 1 1 0
4
0 1 2 0
4
0 0 1 0
4
0 0 1 1
4
0 1 0 0
4
0 1 0 1
4
0 0 0 0
4
0 0 1 0
4
0 0 1 0
4
1 0 1 0
4
0 1 1 0
4
0 1 2...

output:

4
00
01
10
11
0
4
00
01
10
11
0
4
00
01
10
11
0
4
00
01
10
11
0
4
000
010
101
111
0
4
001
011
100
110
4
000
010
101
111
4
000
010
101
111
0
4
001
011
100
110
0
4
001
011
100
110
0
4
000
010
101
111
0
4
001
011
100
110
0
4
000
010
101
111
0
4
0000
0101
1010
1111
0
4
0010
0111
1000
1101
0
4
0001
0100
...

result:

ok 401208 lines