제출 #458462

#제출 시각아이디문제언어결과실행 시간메모리
458462leinad2식물 비교 (IOI20_plants)C++17
100 / 100
2454 ms117532 KiB
#include "plants.h" #include<bits/stdc++.h> using namespace std; int K, i, j, N, R[200010], X[200010], lazy[800010], A[200010], B[200010], sparse1[200010][20], sparse2[200010][20]; long long sparse3[200010][20], sparse4[200010][20]; struct st { int x, y; const bool operator<(st a)const { if(x==a.x)return y<a.y; return x>a.x; } }; set<st>s; struct node { int x, y; }seg[800010]; node merge(node a, node b) { if(a.x<b.x)return a; if(a.x>b.x)return b; return {a.x, min(a.y, b.y)}; } void busy(int id) { seg[id*2].x+=lazy[id]; seg[id*2+1].x+=lazy[id]; lazy[id*2]+=lazy[id]; lazy[id*2+1]+=lazy[id]; lazy[id]=0; } void init(int id, int s, int e) { if(s==e) { seg[id].x=R[s]; seg[id].y=s; return; } int m=s+e>>1; init(id*2, s, m);init(id*2+1, m+1, e); seg[id]=merge(seg[id*2], seg[id*2+1]); } void update(int id, int s, int e, int l, int r, int v) { if(e<l||r<s)return; if(l<=s&&e<=r) { lazy[id]+=v; seg[id].x+=v; return; } busy(id);int m=s+e>>1; update(id*2, s, m, l, r, v);update(id*2+1, m+1, e, l, r, v); seg[id]=merge(seg[id*2], seg[id*2+1]); } node get(int id, int s, int e, int l, int r) { if(e<l||r<s)return {(int)1e9, 0}; if(l<=s&&e<=r)return seg[id]; busy(id);int m=s+e>>1; return merge(get(id*2, s, m, l, r), get(id*2+1, m+1, e, l, r)); } int f(int a) { a%=N; if(a<=0)a+=N; return a; } void init(int k, vector<int>r) { K=k;N=r.size();for(i=0;i++<N;)X[i]=-1; for(i=0;i++<N;)R[i]=r[i-1]; init(1, 1, N); vector<int>v; for(i=0;i++<N;) { if(R[i]==0) { if(i>=K) { node a=get(1, 1, N, i-K+1, i-1); if(a.x)v.push_back(i); } else { node a=merge(get(1, 1, N, 1, i-1), get(1, 1, N, N-K+i+1, N)); if(a.x)v.push_back(i); } } } int group=0; while(v.size()) { vector<int>V; for(auto i:v) { if(i>=K)update(1, 1, N, i-K+1, i-1, -1); else update(1, 1, N, 1, i-1, -1),update(1, 1, N, N-k+i+1, N, -1); X[i]=group;update(1, 1, N, i, i, 1e9); } for(auto i:v) { if(i>=K) { node a=get(1, 1, N, i-K+1, i-1); if(a.x==0)V.push_back(a.y); } else { node a=get(1, 1, N, 1, i-1); node b=get(1, 1, N, N-k+i+1, N); if(b.x==0)V.push_back(b.y); else if(a.x==0)V.push_back(a.y); } if(i<=N-K+1) { node a=get(1, 1, N, i+1, i+K-1); if(a.x==0)V.push_back(a.y); } else { node a=get(1, 1, N, i+1, N); node b=get(1, 1, N, 1, i+K-1-N); if(a.x==0)V.push_back(a.y); else if(b.x==0)V.push_back(b.y); } } sort(V.begin(), V.end()); v.clear(); for(auto i:V) { node a; if(i>=K)a=get(1, 1, N, i-K+1, i-1); else a=merge(get(1, 1, N, 1, i-1), get(1, 1, N, i-K+1+N, N)); if(a.x==0)continue; if(!v.size()||v.back()!=i)v.push_back(i); } group++; } for(i=0;i++<N;)X[i]=N-X[i]; for(j=-K+2;j<=0;j++)s.insert({X[f(j)], j}); for(i=0;i++<N;) { if((*s.rbegin()).x>=X[i])A[i]=i; else A[i]=f((*s.lower_bound({X[i]-1, (int)-1e9})).y); s.erase({X[f(i-K+1)], i-K+1}); s.insert({X[i], i}); } s.clear(); for(i=1;i<=N/2;i++)swap(X[i], X[N+1-i]); for(j=-K+2;j<=0;j++)s.insert({X[f(j)], j}); for(i=0;i++<N;) { if((*s.rbegin()).x>=X[i])B[i]=i; else B[i]=f((*s.lower_bound({X[i]-1, (int)-1e9})).y); s.erase({X[f(i-K+1)], i-K+1}); s.insert({X[i], i}); } for(i=1;i<=N/2;i++)swap(X[i], X[N+1-i]); for(i=0;i++<N;)B[i]=N+1-B[i]; for(i=1;i<=N/2;i++)swap(B[i], B[N+1-i]); for(i=0;i++<N;)sparse1[i][0]=A[i],sparse2[i][0]=B[i]; for(i=0;i++<N;)sparse3[i][0]=f(i-A[i])%N,sparse4[i][0]=f(B[i]-i)%N; for(j=1;j<20;j++) { for(i=0;i++<N;) { sparse1[i][j]=sparse1[sparse1[i][j-1]][j-1]; sparse2[i][j]=sparse2[sparse2[i][j-1]][j-1]; sparse3[i][j]=sparse3[sparse1[i][j-1]][j-1]+sparse3[i][j-1]; sparse4[i][j]=sparse4[sparse2[i][j-1]][j-1]+sparse4[i][j-1]; } } return; } int compare_plants(int x, int y) { if(X[x+1]<X[y+1])return -compare_plants(y, x); x++;y++; int a=x, b=x;long long dist=0, dist2=0; for(j=19;j>=0;j--) { if(X[sparse1[a][j]]>=X[y]) { dist+=sparse3[a][j]; a=sparse1[a][j]; } if(X[sparse2[b][j]]>=X[y]) { dist2+=sparse4[b][j]; b=sparse2[b][j]; } } long long p=x-dist, q=x+dist2; if((p<=y-N&&y-N<=q)||(p<=y&&y<=q)||(p<=y+N&&y+N<=q))return 1; return 0; }

컴파일 시 표준 에러 (stderr) 메시지

plants.cpp: In function 'void init(int, int, int)':
plants.cpp:42:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   42 |     int m=s+e>>1;
      |           ~^~
plants.cpp: In function 'void update(int, int, int, int, int, int)':
plants.cpp:55:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   55 |     busy(id);int m=s+e>>1;
      |                    ~^~
plants.cpp: In function 'node get(int, int, int, int, int)':
plants.cpp:63:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   63 |     busy(id);int m=s+e>>1;
      |                    ~^~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...