This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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();
}
Compilation message (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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |