Submission #300401

#TimeUsernameProblemLanguageResultExecution timeMemory
300401bacegen4oJoker (BOI20_joker)C11
71 / 100
2083 ms14684 KiB
#pragma GCC optimize "-O3" #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<assert.h> #include<stdbool.h> #include<limits.h> #define swap(a,b) do{ __typeof(a) tp; tp=a; a=b; b=tp; }while(0) typedef struct{ int first, second; }pair; pair newpair(int a, int b){ return(pair){a,b}; } int cmpP(const void*pa, const void*pb){ pair*a = (pair*)pa; pair*b = (pair*)pb; if(a->first != b->first) return(a->first < b->first )?-1:1; if(a->second != b->second)return(a->second < b->second)?-1:1; return 0; } #ifndef STB_STRETCHY_BUFFER_H_INCLUDED #define STB_STRETCHY_BUFFER_H_INCLUDED #ifndef NO_STRETCHY_BUFFER_SHORT_NAMES #define sb_free stb_sb_free #define sb_push stb_sb_push #define sb_count stb_sb_count #define sb_add stb_sb_add #define sb_last stb_sb_last #endif #define stb_sb_free(a) ((a) ? free(stb__sbraw(a)),0 : 0) #define stb_sb_push(a,v) (stb__sbmaybegrow(a,1), (a)[stb__sbn(a)++] = (v)) #define stb_sb_count(a) ((a) ? stb__sbn(a) : 0) #define stb_sb_add(a,n) (stb__sbmaybegrow(a,n), stb__sbn(a)+=(n), &(a)[stb__sbn(a)-(n)]) #define stb_sb_last(a) ((a)[stb__sbn(a)-1]) #define stb__sbraw(a) ((int *) (a) - 2) #define stb__sbm(a) stb__sbraw(a)[0] #define stb__sbn(a) stb__sbraw(a)[1] #define stb__sbneedgrow(a,n) ((a)==0 || stb__sbn(a)+(n) >= stb__sbm(a)) #define stb__sbmaybegrow(a,n) (stb__sbneedgrow(a,(n)) ? stb__sbgrow(a,n) : 0) #define stb__sbgrow(a,n) (*((void **)&(a)) = stb__sbgrowf((a), (n), sizeof(*(a)))) static void*stb__sbgrowf(void*arr, int increment, int itemsize){ int dbl_cur = arr ? 2*stb__sbm(arr) : 0; int min_needed = stb_sb_count(arr) + increment; int m = dbl_cur > min_needed ? dbl_cur : min_needed; int*p = (int *) realloc(arr ? stb__sbraw(arr) : 0, itemsize * m + sizeof(int)*2); if(p){ if(!arr) p[1] = 0; p[0] = m; return p+2; } else { #ifdef STRETCHY_BUFFER_OUT_OF_MEMORY STRETCHY_BUFFER_OUT_OF_MEMORY; #endif return(void*)(2*sizeof(int)); } } #endif inline double sqrt(double x){ __asm__ ("fsqrt" : "+t" (x)); return x; } inline int max(int a,int b){return a>b?a:b;} /////////////////////////////////// enum{MAXN = 200005}; enum{MAXM = 200005}; enum{MAXQ = 200005}; int comp[MAXN], h[MAXN]; bool col_switch[MAXN]; int n_mem, mem_cv[MAXM], mem_cu[MAXM], mem_hcu[MAXM]; bool mem_swcv[MAXM]; int N, M, Q; int E[2][MAXM], queries[2][MAXQ], res[MAXQ]; int*inds; void init_dsu(int n){ for(int i=0; i<n; i++){ comp[i] = i; h[i] = 0; col_switch[i] = 0; } n_mem = 0; } pair find(int v){ bool col = col_switch[v]; while(comp[v] != v){ v = comp[v]; col ^= 1; col ^= col_switch[v]; } return newpair(v, col); } void merge(int v, int u){ pair ansv = find(v), ansu = find(u); int cv = ansv.first, cu = ansu.first; bool colv = ansv.second, colu = ansu.second; if(cv != cu){ if(h[cv] > h[cu]){ swap(cv, cu); swap(v, u); } mem_cv [n_mem] = cv; mem_cu [n_mem] = cu; mem_hcu [n_mem] = h[cu]; mem_swcv[n_mem] = col_switch[cv]; n_mem++; comp[cv] = cu; if(h[cv] == h[cu]) h[cu]++; col_switch[cv] = (colv != colu); } else{ mem_cv[n_mem] = -1; n_mem++; } } int check(int v, int u){ pair ansv = find(v), ansu = find(u); int cv = ansv.first, cu = ansu.first; bool colv = ansv.second, colu = ansu.second; if(cv != cu) return 2; if(colv == colu) return -1; return 1; } void rollback(int k){ while(k--){ n_mem--; int cv = mem_cv[n_mem], cu = mem_cu[n_mem]; bool swcv = mem_swcv[n_mem]; if(cv == -1) continue; comp[cv] = cv; h[cu] = cu; col_switch[cv] = swcv; } } void solve_for_inds(int e_left_next){ int k = sb_count(inds); pair v[k]; for(int i=0; i<k; i++){ int ind = inds[i]; v[i] = newpair(-queries[1][ind], ind); } qsort(v, k, sizeof(pair), cmpP); int e_right_next = M-1, steps = 0; bool got_cycle = false; for(int i = 0; i < k; i++){ int ind = v[i].second; int L = queries[0][ind], R = queries[1][ind]; if(!got_cycle){ while(e_right_next > R){ int status = check(E[0][e_right_next], E[1][e_right_next]); if(status == -1){ got_cycle = true; break; } merge(E[0][e_right_next], E[1][e_right_next]); e_right_next--; steps++; } } bool got_cycle_inner = got_cycle; int steps_inner = 0; if(!got_cycle_inner){ for (int e = e_left_next; e < L; e++) { int status = check(E[0][e], E[1][e]); if(status == -1){ got_cycle_inner = true; break; } merge(E[0][e], E[1][e]); steps_inner++; } } res[ind] = (int)(got_cycle || got_cycle_inner); rollback(steps_inner); } rollback(steps); } void solve(){ int B = max((int)(M / sqrt(Q)), 1); pair v[Q]; for(int i = 0; i < Q; i++){ v[i] = newpair(queries[0][i] / B, i); } qsort(v, Q, sizeof(pair), cmpP); init_dsu(N); int e_left_next = 0; bool got_cycle = false; if(inds) sb_free(inds); inds = NULL; for(int i=0; i<Q; i++){ sb_push(inds, v[i].second); if(i + 1 == Q || v[i].first != v[i+1].first){ while(!got_cycle && e_left_next < v[i].first * B){ int status = check(E[0][e_left_next], E[1][e_left_next]); if(status == -1){ got_cycle = true; break; } merge(E[0][e_left_next], E[1][e_left_next]); e_left_next++; } if(got_cycle){ for(int j = 0; j<sb_count(inds); j++){ int ind = inds[j]; res[ind] = 1; } } else{ solve_for_inds(e_left_next); } if(inds) sb_free(inds); inds = NULL; } } } int main(){ while(scanf("%d%d%d", &N, &M, &Q)==3){ for(int i = 0; i < M; i++){ scanf("%d %d", &E[0][i], &E[1][i]); E[0][i]--; E[1][i]--; } for(int i = 0; i < Q; i++){ scanf("%d %d", &queries[0][i], &queries[1][i]); queries[0][i]--; queries[1][i]--; } solve(); for(int i = 0; i < Q; i++){ if (res[i]) puts("YES"); else puts("NO"); } } return 0; }

Compilation message (stderr)

Joker.c: In function 'main':
Joker.c:239:13: warning: ignoring return value of 'scanf', declared with attribute warn_unused_result [-Wunused-result]
  239 |             scanf("%d %d", &E[0][i], &E[1][i]);
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Joker.c:244:13: warning: ignoring return value of 'scanf', declared with attribute warn_unused_result [-Wunused-result]
  244 |             scanf("%d %d", &queries[0][i], &queries[1][i]);
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...