제출 #1105211

#제출 시각아이디문제언어결과실행 시간메모리
1105211VinhLuuRailway Trip 2 (JOI22_ho_t4)C++17
100 / 100
446 ms126208 KiB
#include <bits/stdc++.h> //#define int long long #define ll long long using namespace std; const int N = 2e5 + 5; const int oo = 1e9; int n, m, k, q, a[N], b[N], _s[N], _t[N]; int le[N], ri[N], f[N]; int st[2][N << 2]; void build(int i,int l,int r){ if(l == r){ st[0][i] = st[1][i] = l; return; } int mid = (l + r) / 2; build(i << 1, l, mid); build(i << 1|1, mid + 1, r); st[0][i] = n + 1; st[1][i] = 0; } void dolz(int i){ if(st[0][i] != n + 1){ int x = st[0][i]; st[0][i] = n + 1; st[0][i << 1] = min(st[0][i << 1], x); st[0][i << 1|1] = min(st[0][i << 1|1], x); } if(st[1][i] != 0){ int x = st[1][i]; st[1][i] = 0; st[1][i << 1] = max(st[1][i << 1], x); st[1][i << 1|1] = max(st[1][i << 1|1], x); } } void update(int i,int l,int r,int u,int v,int val,int type){ if(l > r || r < u || v < l) return; if(u <= l && r <= v){ if(!type) st[0][i] = min(st[0][i], val); else st[1][i] = max(st[1][i], val); return; } dolz(i); int mid = (l + r) / 2; update(i << 1, l, mid, u, v, val, type); update(i << 1|1, mid + 1, r, u, v, val, type); } void done(int i,int l,int r){ if(l == r){ le[l] = st[0][i]; ri[l] = st[1][i]; return; } dolz(i); int mid = (l + r) / 2; done(i << 1, l, mid); done(i << 1|1, mid + 1, r); } void pre(){ build(1, 1, n); for(int i = 1; i <= m; i ++){ if(a[i] < b[i]){ update(1, 1, n, a[i], min(a[i] + k - 1, b[i] - 1), b[i], 1); }else{ update(1, 1, n, max(a[i] - k + 1, b[i] + 1), a[i], b[i], 0); } } done(1, 1, n); } namespace sub3{ int f[N]; void solve(){ pre(); for(int k = 1; k <= q; k ++){ int x = _s[k], y = _t[k]; queue<int> q; for(int i = 1; i <= n; i ++) f[i] = oo; for(int i = le[x]; i <= ri[x]; i ++){ f[i] = 1; q.push(i); } int pl = le[x], pr = ri[x]; f[x] = 0; while(!q.empty()){ int u = q.front(); q.pop(); if(le[u] < pl){ for(int i = le[u]; i <= pl - 1; i ++){ f[i] = f[u] + 1; q.push(i); } pl = le[u]; } if(ri[u] > pr){ for(int i = pr + 1; i <= ri[u]; i ++){ f[i] = f[u] + 1; q.push(i); } pr = ri[u]; } } if(f[y] == oo){ cout << -1 << "\n"; continue; }else cout << f[y] << "\n"; } } } namespace AC{ int kq[N]; vector<int> Q[N]; int f[22][N], g[22][N], LG[N], dp[2][18][100005]; int get_max(int l,int r){ int k = LG[r - l + 1]; return max(dp[1][k][l], dp[1][k][r - (1 << k) + 1]); } struct ST{ int T[2][N << 1]; void change(int i,int x,int y){ i += n - 1; T[0][i] = x; T[1][i] = y; while(i > 1){ i /= 2; T[0][i] = min(T[0][i << 1], T[0][i << 1|1]); T[1][i] = max(T[1][i << 1], T[1][i << 1|1]); } } int Min(int l,int r){ if(l > r) return n + 1; r++; int ret = n + 1; for(l += n - 1, r += n - 1; l < r; l /= 2, r /= 2){ if(l & 1) ret = min(ret, T[0][l ++]); if(r & 1) ret = min(ret, T[0][-- r]); } return ret; } int Max(int l,int r){ if(l > r) return 0; r++; int ret = 0; for(l += n - 1, r += n - 1; l < r; l /= 2, r /= 2){ if(l & 1) ret = max(ret, T[1][l ++]); if(r & 1) ret = max(ret, T[1][-- r]); } return ret; } } tree[19]; int get_min(int l,int r){ int k = LG[r - l + 1]; return min(dp[0][k][l], dp[0][k][r - (1 << k) + 1]); } void solve(){ pre(); int pre = 0, nx = 1; for(int i = 1; i <= n; i ++){ LG[i] = (i == 1 ? 0 : LG[i / 2] + 1); f[0][i] = le[i], g[0][i] = ri[i]; } // pre/nx - type - log - i for(int k = 0; k <= 17; k ++){ if(k > 0) for(int i = 1; i <= n; i ++){ f[k][i] = get_min(f[k - 1][i], g[k - 1][i]); g[k][i] = get_max(f[k - 1][i], g[k - 1][i]); // if(k <= 3) cerr << i << " " << k << " " << f[k][i] << " " << g[k][i] << " jjj\n"; } for(int i = 1; i <= n; i ++) tree[k].change(i, f[k][i], g[k][i]); swap(pre, nx); for(int i = n; i >= 1; i --){ dp[0][0][i] = f[k][i]; dp[1][0][i] = g[k][i]; for(int j = 1; j <= 17 && i + (1 << j) - 1 <= n; j ++){ dp[0][j][i] = min(dp[0][j - 1][i], dp[0][j - 1][i + (1 << (j - 1))]); dp[1][j][i] = max(dp[1][j - 1][i], dp[1][j - 1][i + (1 << (j - 1))]); } } } for(int t = 1; t <= q; t ++){ int x = _s[t], y = _t[t]; int cnt = 0; if(f[0][x] <= y && y <= g[0][x]){ cout << 1 << "\n"; continue; } if(f[17][x] > y || g[17][x] < y){ cout << -1 << "\n"; continue; } int l = x, r = x; for(int j = 17; j >= 0; j --){ int _left = tree[j].Min(l, r); int _right = tree[j].Max(l, r); // cerr << j << " " << j << " " << l << " " << r << " " << _left << " " << _right << " g\n"; if(_left > y || _right < y){ cnt += (1 << j); // cerr << cnt << " choose\n"; l = _left, r = _right; } } cout << cnt + 1 << "\n"; } } } signed main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); #define task "v" if(fopen(task ".inp","r")){ freopen(task ".inp","r",stdin); freopen(task ".out","w",stdout); } cin >> n >> k >> m; for(int i = 1; i <= m; i ++) cin >> a[i] >> b[i]; cin >> q; for(int i = 1; i <= q; i ++) cin >> _s[i] >> _t[i]; AC :: solve(); }

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

Main.cpp: In function 'int main()':
Main.cpp:233:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  233 |     freopen(task ".inp","r",stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:234:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  234 |     freopen(task ".out","w",stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
#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...