QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#708511 | #8301. Hold the Line | Lavender_Field | TL | 0ms | 0kb | C++20 | 5.9kb | 2024-11-03 23:05:29 | 2024-11-03 23:05:30 |
answer
// 先对 xh[i] 离散化,保证权值线段树为 O(n)
// 每个 xh[i] 处理 出现时间 t 和 出现位置 v,则询问要求 qt >= t, v >= ql.
// 从左到右更新,保证了 v 单增。此时若 t' < t, 则可以 pop_back.
#include <bits/stdc++.h>
#define FOR(i,a,b) for(int i = a; i <= b; ++i)
using namespace std;
inline int rd() {
int r = 0; bool w = false; char ch = getchar();
while( ch < '0' || ch > '9' ) w = !(ch^45), ch = getchar();
while( ch >= '0' && ch <= '9' ) r = (r<<1) + (r<<3) + (ch^48), ch = getchar();
return w ? -r : r;
}
#define MAXN 500000
#define MAXM 1000000
int n, m;
int xh[MAXN+5];
int xt[MAXN+5];
pair<int, int> xhbuc[MAXN+5]; int xhbuctot; // 排序用
int xhbac[MAXN+5]; int xhbactot; // 离散化后反函数
struct Query_t {
int l, r, h;
int t;
int ans;
Query_t(): ans(-1) {}
Query_t(int li, int ri, int hi, int ti): l(li), r(ri), h(hi), t(ti), ans(-1) {}
};
vector<Query_t> qvec[MAXN+5];
pair<int, int> ans[MAXM+5]; int anstot;
vector<pair<int, int> > arr[MAXN*4+5]; // 第一维存位置,单增;第二维存时间,也单增
int isleaf[MAXN*4+5];
#define lson (p<<1)
#define rson ((p<<1)+1)
void build( int p = 1 , int L = 1 , int R = xhbactot ) {
arr[p].clear();
if( L == R ) {
isleaf[p] = L;
return;
}
int mid = (L + R) >> 1;
isleaf[p] = 0;
build(lson, L, mid);
build(rson, mid+1, R);
}
void update( int x , int t , int v , int p = 1 , int L = 1 , int R = xhbactot ) {
while( !arr[p].empty() && arr[p].back().second > t ) arr[p].pop_back();
arr[p].push_back(make_pair(v, t));
if( L == R ) return;
int mid = (L + R) >> 1;
if( x <= mid ) update(x, t, v, lson, L, mid);
else update(x, t, v, rson, mid+1, R);
}
bool chkValid( const vector<pair<int, int> > &vec, int t, int v ) { // 查找是否有可行点
int l = 0, r = vec.size() - 1, ag = r+1; // 找 v,需要 >=
while( l <= r ) {
int mid = (l + r) >> 1;
if( vec[mid].first >= v ) {
r = mid-1;
ag = mid;
} else l = mid+1;
}
l = 0, r = vec.size() - 1; int ag2 = -1; // 找 t,需要 <
while( l <= r ) {
int mid = (l + r) >> 1;
if( vec[mid].second < t ) {
l = mid+1;
ag2 = mid;
} else r = mid-1;
}
return ag <= ag2;
}
int querypre( int x , int t , int v , int p = 1 , int L = 1 , int R = xhbactot ) {
// printf("querypre: %d %d %d\n", x, t, v);
while( L != R ) {
int mid = (L + R) >> 1;
if( x <= mid ) p = lson, R = mid;
else p = rson, L = mid + 1;
}
if( chkValid(arr[p], t, v) ) return L;
while( p != 1 && (((p & 1) == 0) || !chkValid(arr[p-1], t, v)) ) p >>= 1;
if( p == 1 ) return -1;
p -= 1;
while( !isleaf[p] ) {
if( chkValid(arr[rson], t, v) ) p = rson;
else p = lson;
}
if( chkValid(arr[p], t, v) ) return isleaf[p];
else return -1;
}
int querynxt( int x , int t , int v , int p = 1 , int L = 1 , int R = xhbactot ) {
while( L != R ) {
int mid = (L + R) >> 1;
if( x <= mid ) p = lson, R = mid;
else p = rson, L = mid + 1;
}
if( chkValid(arr[p], t, v) ) return L;
while( p != 1 && (((p & 1) == 1) || !chkValid(arr[p+1], t, v)) ) p >>= 1;
if( p == 1 ) return -1;
p += 1;
while( !isleaf[p] ) {
if( chkValid(arr[lson], t, v) ) p = lson;
else p = rson;
}
if( chkValid(arr[p], t, v) ) return isleaf[p];
else return -1;
}
void solve() {
n = rd(), m = rd();
xhbuctot = 0;
xhbactot = 0;
FOR(i,1,n) xh[i] = xt[i] = 0;
FOR(i,1,n) qvec[i].clear();
anstot = 0;
FOR(i,1,m) {
int typ = rd();
if( typ == 0 ) {
int x = rd();
xh[x] = rd();
xt[x] = i;
xhbuc[++xhbuctot] = make_pair(xh[x], x);
} else {
int l = rd(), r = rd(), h = rd();
qvec[r].push_back(Query_t(l, r, h, i));
}
}
sort(xhbuc+1, xhbuc+1+xhbuctot);
FOR(i,1,xhbuctot) {
if( i > 1 && i <= n && xhbuc[i].first == xhbuc[i-1].first ) {
xh[xhbuc[i].second] = xhbactot;
++i;
}
if( i > n ) break;
xhbac[++xhbactot] = xhbuc[i].first;
xh[xhbuc[i].second] = xhbactot;
}
build();
FOR(i,1,n) {
if( xh[i] ) update(xh[i], xt[i], i);
for(auto &v: qvec[i]) {
int l = 1, r = xhbactot, ag = 0;
while( l <= r ) {
int mid = (l+r) >> 1;
if( xhbac[mid] <= mid ) {
ag = mid;
l = mid+1;
} else r = mid-1;
}
if( ag != 0 ) {
int cons = querypre(ag, v.t, v.l);
if( cons != -1 ) {
if( v.ans == -1 ) v.ans = v.h - xhbac[cons];
else v.ans = min(v.ans, v.h - xhbac[cons]);
}
}
l = 1, r = xhbactot, ag = 0;
while( l <= r ) {
int mid = (l + r) >> 1;
if( xhbac[mid] >= v.h ) {
ag = mid;
r = mid - 1;
} else l = mid + 1;
}
if( ag != 0 ) {
int cons = querynxt(v.h, v.t, v.l);
if( cons != -1 ) {
if( v.ans == -1 ) v.ans = xhbac[cons] - v.h;
else v.ans = min(v.ans, xhbac[cons] - v.h);
}
}
ans[++anstot] = make_pair(v.t, v.ans);
}
}
sort(ans+1, ans+1+anstot);
FOR(i,1,anstot) printf("%d\n", ans[i].second);
}
int main() {
freopen("data.txt", "r", stdin);
int T = rd(); while( T-- ) solve();
return 0;
}
/*
1
3 5
1 1 3 2
0 1 1
0 3 3
1 1 2 2
1 2 3 2
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Time Limit Exceeded
input:
1 3 5 1 1 3 2 0 1 1 0 3 3 1 1 2 2 1 2 3 2