laekov

HDOJ5107 K-short Problem

前天晚上的best coder的题。


数据太弱暴力都放过去了,而且还是错的。当然我也太naive了TT。


我没管k<=10,直接硬上树状数组套平衡树,用二分搞的。然后数组开小了不开心啊。


#include <cstdio>

#include <cmath>

#include <cctype>

#include <algorithm>

#include <set>

#include <memory.h>


using namespace std;


struct query {

int x, y, k, n;

};

struct tower {

int x, y, h;

};


inline bool cmpTower(const tower& a, const tower& b) {

return a. x < b. x;

}


inline bool cmpQuery(const query& a, const query& b) {

return a. x < b. x;

}


inline bool cmpP(int* a, int* b) {

return *a < *b;

}


const int maxn = 30009;

const int maxl = 19;

const int maxv = 1e9 + 9;


int n, m, *rx[maxn * 2], *ry[maxn * 2], mx, my;

int ans[maxn];

tower a[maxn];

query q[maxn];

int t[maxn * 2];


namespace sbt {

const int maxnd = maxn * maxl;

int sz[maxnd], ls[maxnd], rs[maxnd], vl[maxnd], tn;

void init() {

tn = 0;

sz[0] = 0;

}

inline void lRot(int& p) {

int q = rs[p];

rs[p] = ls[q];

ls[q] = p;

sz[q] = sz[p];

sz[p] = sz[ls[p]] + sz[rs[p]] + 1;

p = q;

}

inline void rRot(int& p) {

int q = ls[p];

ls[p] = rs[q];

rs[q] = p;

sz[q] = sz[p];

sz[p] = sz[ls[p]] + sz[rs[p]] + 1;

p = q;

}

inline void maintain(int& p, bool dir) {

if (dir) {

if (sz[ls[p]] > sz[rs[p]] + 1)

rRot(p);

}

else

if (sz[ls[p]] + 1 < sz[rs[p]])

lRot(p);

}

void ins(int& p, int v) {

if (!p) {

p = ++ tn;

ls[p] = 0;

rs[p] = 0;

sz[p] = 1;

vl[p] = v;

}

else {

if (v < vl[p])

ins(ls[p], v);

else

ins(rs[p], v);

++ sz[p];

maintain(p, v < vl[p]);

}

}

int cntLower(int p, int v) {

if (!p)

return 0;

else if (vl[p] <= v)

return sz[ls[p]] + 1 + cntLower(rs[p], v);

else

return cntLower(ls[p], v);

}

};


void dispNums() {

mx = 0;

sort(rx, rx + n + m, cmpP);

for (int i = 0, l = *rx[0] - 1; i < n + m; ++ i)

if (*rx[i] == l)

*rx[i] = mx;

else

l = *rx[i], *rx[i] = ++ mx;

my = 0;

sort(ry, ry + n + m, cmpP);

for (int i = 0, l = *ry[0] - 1; i < n + m; ++ i)

if (*ry[i] == l)

*ry[i] = my;

else

l = *ry[i], *ry[i] = ++ my;

}


void sov() {

sbt :: init();

memset(t, 0, sizeof(t));

for (int i = 0, j = 0; j < m; ++ j) {

while (i < n && a[i]. x <= q[j]. x) {

for (int p = a[i]. y; p <= my; p += (p & -p))

sbt :: ins(t[p], a[i]. h);

++ i;

}

int l = 0, r = maxv;

while (l < r) {

int mid = (l + r) >> 1;

int cnt = 0;

for (int p = q[j]. y; p; p -= (p & -p))

cnt += sbt :: cntLower(t[p], mid);

if (cnt >= q[j]. k)

r = mid;

else

l = mid + 1;

}

if (l == maxv)

ans[q[j]. n] = -1;

else

ans[q[j]. n] = l;

}

}


int main() {

#ifndef ONLINE_JUDGE

freopen("in.txt", "r", stdin);

#endif


while (scanf("%d%d", &n, &m) != EOF) {

for (int i = 0; i < n; ++ i) {

scanf("%d%d%d", &a[i]. x, &a[i]. y, &a[i]. h);

rx[i] = &a[i]. x;

ry[i] = &a[i]. y;

}

for (int i = 0; i < m; ++ i) {

scanf("%d%d%d", &q[i]. x, &q[i]. y, &q[i]. k);

q[i]. n = i;

rx[i + n] = &q[i]. x;

ry[i + n] = &q[i]. y;

}

dispNums();

sort(a, a + n, cmpTower);

sort(q, q + m, cmpQuery);

sov();

for (int i = 0; i < m; ++ i)

printf("%d\n", ans[i]);

}

}



评论

© laekov | Powered by LOFTER