Submission #44886

#TimeUsernameProblemLanguageResultExecution timeMemory
44886RayaBurong25_1Security Gate (JOI18_security_gate)C++17
12 / 100
5019 ms1980 KiB
#include <stdio.h> #include <vector> #define INF 1000000007 char S[305]; std::vector<int> Xpos; std::vector<char> ChangeBit; typedef struct node node; struct node { int v; int sum, sumrev; int mn, mnrev; }; int N; node Seg[1205]; int Fen[305]; int Q[305]; void up(int p, int v) { p++; for (; p <= N; p += p&-p) Fen[p] += v; } int qu(int p) { p++; int r = 0; for (; p > 0; p -= p&-p) r += Fen[p]; return r; } int min(int a, int b) { return (a < b)?a:b; } int max(int a, int b) { return (a > b)?a:b; } void makeTree(int s, int e, int cell) { if (s == e) { Seg[cell].v = ((S[s] == '(')?1:-1); Seg[cell].sum = Seg[cell].v; Seg[cell].sumrev = -Seg[cell].v; Seg[cell].mn = Seg[cell].v; Seg[cell].mnrev = -Seg[cell].v; return; } int m = (s + e)/2; makeTree(s, m, 2*cell + 1); makeTree(m + 1, e, 2*cell + 2); Seg[cell].sum = Seg[2*cell + 1].sum + Seg[2*cell + 2].sum; Seg[cell].sumrev = Seg[2*cell + 1].sumrev + Seg[2*cell + 2].sumrev; Seg[cell].mn = min(Seg[2*cell + 1].mn, Seg[2*cell + 1].sum + Seg[2*cell + 2].mn); Seg[cell].mnrev = min(Seg[2*cell + 1].mnrev, Seg[2*cell + 1].sumrev + Seg[2*cell + 2].mnrev); } void preprocess() { int i; for (i = 0; i < N; i++) { up(i, ((S[i] == '(')?1:-1)); Q[i] = qu(i); // printf("Q %d ", Q[i]); } makeTree(0, N - 1, 0); } void update(int p, int s, int e, int cell) { if (s == e) { // printf("update p = %c\n", S[s]); Seg[cell].v = ((S[s] == '(')?1:-1); Seg[cell].sum = Seg[cell].v; Seg[cell].sumrev = -Seg[cell].v; Seg[cell].mn = Seg[cell].v; Seg[cell].mnrev = -Seg[cell].v; return; } int m = (s + e)/2; if (p <= m) update(p, s, m, 2*cell + 1); else update(p, m + 1, e, 2*cell + 2); Seg[cell].sum = Seg[2*cell + 1].sum + Seg[2*cell + 2].sum; Seg[cell].sumrev = Seg[2*cell + 1].sumrev + Seg[2*cell + 2].sumrev; Seg[cell].mn = min(Seg[2*cell + 1].mn, Seg[2*cell + 1].sum + Seg[2*cell + 2].mn); Seg[cell].mnrev = min(Seg[2*cell + 1].mnrev, Seg[2*cell + 1].sumrev + Seg[2*cell + 2].mnrev); } void change(int i) { up(i, ((S[i] == '(')?2:-2)); update(i, 0, N - 1, 0); for (; i < N; i++) Q[i] = qu(i); // for (i = 0; i < N; i++) // printf("Q %d ", Q[i]); } node query(int qs, int qe, int s, int e, int cell) { // printf("query %d %d %d %d %d\n", qs, qe, s, e, cell); if (qs == s && qe == e) return Seg[cell]; int m = (s + e)/2; node l = {INF, 0, 0, INF, INF}; node r = {INF, 0, 0, INF, INF}; if (qs <= m) l = query(qs, min(m, qe), s, m, 2*cell + 1); if (m + 1 <= qe) r = query(max(m + 1, qs), qe, m + 1, e, 2*cell + 2); node ret; ret.sum = l.sum + r.sum; ret.sumrev = l.sumrev + r.sumrev; ret.mn = min(l.mn, l.sum + r.mn); ret.mnrev = min(l.mnrev, l.sumrev + r.mnrev); // printf("l %d %d %d %d\n", l.sum, l.sumrev, l.mn, l.mnrev); // printf("r %d %d %d %d\n", r.sum, r.sumrev, r.mn, r.mnrev); // printf("ret %d %d %d %d\n", ret.sum, ret.sumrev, ret.mn, ret.mnrev); return ret; } int checkrange(int i, int j) { int mn = INF; node p; if (i > 0) { p = query(0, i - 1, 0, N - 1, 0); mn = min(mn, p.mn); // printf("{%d %d %d %d %d} mn %d\n", p.v, p.sum, p.sumrev, p.mn, p.mnrev, mn); } p = query(i, j, 0, N - 1, 0); mn = min(mn, ((i > 0)?Q[i - 1]:0) + p.mnrev); // printf("{%d %d %d %d %d} mn %d\n", p.v, p.sum, p.sumrev, p.mn, p.mnrev, mn); if (j < N - 1) { p = query(j + 1, N - 1, 0, N - 1, 0); mn = min(mn, 2*((i > 0)?Q[i - 1]:0) - Q[j] + p.mn); // printf("{%d %d %d %d %d} mn %d\n", p.v, p.sum, p.sumrev, p.mn, p.mnrev, mn); } // printf("mn %d\n", mn); return (mn == 0); } int check() { if (Q[N - 1]%2) return 0; else if (Q[N - 1] == 0 && query(0, N - 1, 0, N - 1, 0).mn == 0) return 1; int i, j, q; std::vector<int> V[610]; V[N].push_back(-1); for (i = 0; i < N; i++) { q = Q[i] - Q[N - 1]/2; for (j = 0; j < V[q + N].size(); j++) { // printf("%d %d\n", V[q + N][j] + 1, i); if (checkrange(V[q + N][j] + 1, i)) return 1; } V[Q[i] + N].push_back(i); } return 0; } void printTree(int s, int e, int cell) { if (s == e) { printf("(%d %d) %d %d %d %d %d\n", s, e, Seg[cell].v, Seg[cell].sum, Seg[cell].sumrev, Seg[cell].mn, Seg[cell].mnrev); return; } int m = (s + e)/2; printTree(s, m, 2*cell + 1); printf("(%d %d) %d %d %d %d %d\n", s, e, Seg[cell].v, Seg[cell].sum, Seg[cell].sumrev, Seg[cell].mn, Seg[cell].mnrev); printTree(m + 1, e, 2*cell + 2); } int main() { scanf("%d", &N); int i, X = 0; scanf("%s", S); for (i = 0; i < N; i++) { if (S[i] == 'x') { Xpos.push_back(i); X++; S[i] = '('; } } int j, s; for (i = 0; i < X; i++) { ChangeBit.push_back(i); s = ChangeBit.size(); for (j = 0; j < s - 1; j++) ChangeBit.push_back(ChangeBit[j]); } int cnt = 0; // printf("%s\n", S); preprocess(); // printTree(0, N - 1, 0); if (check()) cnt++; for (i = 0; i < ChangeBit.size(); i++) { if (S[Xpos[ChangeBit[i]]] == '(') S[Xpos[ChangeBit[i]]] = ')'; else S[Xpos[ChangeBit[i]]] = '('; // printf("%s\n", S); change(Xpos[ChangeBit[i]]); // printTree(0, N - 1, 0); if (check()) cnt++; } printf("%d", cnt); }

Compilation message (stderr)

securitygate.cpp: In function 'int check()':
securitygate.cpp:157:23: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for (j = 0; j < V[q + N].size(); j++)
                     ~~^~~~~~~~~~~~~~~~~
securitygate.cpp: In function 'int main()':
securitygate.cpp:207:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for (i = 0; i < ChangeBit.size(); i++)
                 ~~^~~~~~~~~~~~~~~~~~
securitygate.cpp:181:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &N);
     ~~~~~^~~~~~~~~~
securitygate.cpp:183:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%s", S);
     ~~~~~^~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...