QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#708511#8301. Hold the LineLavender_FieldTL 0ms0kbC++205.9kb2024-11-03 23:05:292024-11-03 23:05:30

Judging History

你现在查看的是最新测评结果

  • [2024-11-03 23:05:30]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-11-03 23:05:29]
  • 提交

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

output:


result: