laekov

BZOJ2716 [Violet 3]天使玩偶

看时间比较宽么,写一个log^2的cdq+树状数组么。


然后被2648卡了。学kd-tree吧。


naive。


#include <cstdio>

#include <cctype>

#include <cstring>

#include <algorithm>


using namespace std;


int _d_;

#define readInt(_s_) {\

_s_ = 0;\

while (!isdigit(_d_ = getchar()));\

while ((_s_ = _s_ * 10 + _d_ - 48), isdigit(_d_ = getchar()));\

}


struct point {

int x, y, t, i;

};


const int maxn = 500009;

const int maxz = 1000009;

const int inf = 0x3f3f3f3f;


inline bool cmpPoint(const point& a, const point& b) {

return a. x < b. x;

}


int maxa;


struct pbt {

int t[maxz], r[maxz], ttm;

void init() {

memset(r, 0, sizeof(r));

ttm = 0;

}

inline void next() {

++ ttm;

}

void chg(int p, int v) {

for (; p < maxa; p += (p & -p))

if (r[p] == ttm)

t[p] = max(t[p], v);

else

r[p] = ttm, t[p] = v;

}

int qry(int p) {

int s = -inf;

for (; p; p -= (p & -p))

if (r[p] == ttm)

s = max(t[p], s);

return s;

}

};


int m, n, ans[maxn];

point a[maxn], b[maxn], tmp[maxn];

pbt tu, td;


void calcEff(point* a, int l, int p, int q) {

tu. next();

td. next();

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

for (; i < l && a[i]. x <= b[j]. x; ++ i) {

tu. chg(maxa - a[i]. y, a[i]. x - a[i]. y);

td. chg(a[i]. y, a[i]. x + a[i]. y);

}

int vu = b[j]. x - b[j]. y - tu. qry(maxa - b[j]. y);

int vd = b[j]. x + b[j]. y - td. qry(b[j]. y);

int vn = min(vu, vd);

ans[b[j]. i] = min(ans[b[j]. i], vn);

}

tu. next();

td. next();

for (int i = l - 1, j = q - 1; j >= p; -- j) {

for (; i >= 0 && a[i]. x >= b[j]. x; -- i) {

tu. chg(maxa - a[i]. y, -a[i]. x - a[i]. y);

td. chg(a[i]. y, -a[i]. x + a[i]. y);

}

int vu = - b[j]. x - b[j]. y - tu. qry(maxa - b[j]. y);

int vd = - b[j]. x + b[j]. y - td. qry(b[j]. y);

int vn = min(vu, vd);

ans[b[j]. i] = min(ans[b[j]. i], vn);

}

}


int cdq(int l, int r) {

if (l + 1 == r) {

if (b[l]. t == 2)

return r;

else

return l;

}

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

int xl = cdq(l, mid);

int xr = cdq(mid, r);

calcEff(b + xl, mid - xl, mid, xr);

int tx = l, ty;

for (int i = l, j = mid; i < xl || j < xr;)

if (j == xr || (i < xl && b[i]. x < b[j]. x))

tmp[tx ++] = b[i ++];

else

tmp[tx ++] = b[j ++];

ty = tx;

for (int i = xl, j = xr; i < mid || j < r;)

if (j == r || (i < mid && b[i]. x < b[j]. x))

tmp[ty ++] = b[i ++];

else

tmp[ty ++] = b[j ++];

for (int i = l; i < r; ++ i)

b[i] = tmp[i];

return tx;

}


int main() {

#ifndef ONLINE_JUDGE

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

#endif


tu. init();

td. init();

readInt(m);

readInt(n);

maxa = 0;

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

readInt(a[i]. x);

readInt(a[i]. y);

maxa = max(maxa, max(a[i]. x, a[i]. y));

}

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

readInt(b[i]. t);

readInt(b[i]. x);

readInt(b[i]. y);

maxa = max(maxa, max(b[i]. x, b[i]. y));

b[i]. i = i;

if (b[i]. t == 2)

ans[i] = inf;

else

ans[i] = -1;

}

++ maxa;

int x = cdq(0, n);

sort(a, a + m, cmpPoint);

calcEff(a, m, 0, x);

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

if (ans[i] > -1)

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

}


评论

© laekov | Powered by LOFTER