离线处理+扫描线。题意很容易转化:若干个矩形形成并集,询问一些点是否在并集中?
官方题解不是这样做的....那种做法效率更高,暂时还不会。我这样是4500ms G++过的,C++TLE......
区间加上某值,询问单点值,可以用树状数组。用线段树可能常数较大导致TLE。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<iostream> using namespace std; typedef long long LL; const double pi = acos(-1.0), eps = 1e-8; void File() { freopen("D:\\in.txt", "r", stdin); freopen("D:\\out.txt", "w", stdout); } inline int read() { char c = getchar(); while (!isdigit(c)) c = getchar(); int x = 0; while (isdigit(c)) { x = x * 10 + c - ‘0‘; c = getchar(); } return x; } int T, n, ps, pq, v[1010], c[2000000 + 10]; int A[2000000 + 10], sz; struct Seg { int x, y1, y2, f; }s[2000000 + 10]; int ns; struct Quary { int x, y, id; }q[500000 + 10]; int nq; int ans[500000 + 10]; int lowbit(int x) { return x&(-x); } void add(int p, int val) { while (p <= sz) c[p] = c[p] + val, p = p + lowbit(p); } int sum(int p) { int r = 0; while (p > 0) r = r + c[p], p = p - lowbit(p); return r; } void update(int L, int R, int val) { add(L, val); add(R + 1, -val); } void AddSeg(int l, int r, int L, int R) { s[ns].x = l, s[ns].y1 = L, s[ns].y2 = R, s[ns].f = 1, ns++; s[ns].x = r, s[ns].y1 = L, s[ns].y2 = R, s[ns].f = -1, ns++; A[sz++] = L, A[sz++] = R; } bool cmp(Seg a, Seg b) { if (a.x == b.x) return a.f > b.f; return a.x < b.x; } bool cmp2(Quary a, Quary b) { return a.x < b.x; } void get() { int x = lower_bound(A, A + sz, q[pq].y) - A; x++; if (sum(x) > 0) ans[q[pq].id] = 1; else ans[q[pq].id] = 0; pq++; } void insert() { int L = lower_bound(A, A + sz, s[ps].y1) - A; L++; int R = lower_bound(A, A + sz, s[ps].y2) - A; R++; update(L, R, s[ps].f); ps++; } int main() { scanf("%d", &T); while (T--) { scanf("%d%d", &n, &nq); for (int i = 1; i <= n; i++) scanf("%d", &v[i]); ns = 0; sz = 0; for (int i = 1; i <= n; i++) { int l = 0, r = 0, L = 0, R = 0, w = 0, b = 0; if (i & 1) AddSeg(0, v[i], 0, 0); else AddSeg(0, 0, 0, v[i]); for (int j = i + 1; j <= n; j++) { l = r = w; L = R = b; if (i & 1) r = r + v[i]; else R = R + v[i]; if (j & 1) r = r + v[j]; else R = R + v[j]; AddSeg(l, r, L, R); if (j & 1) w = w + v[j]; else b = b + v[j]; } } for (int i = 0; i < nq; i++) { scanf("%d%d", &q[i].x, &q[i].y); q[i].id = i; A[sz++] = q[i].y; } sort(s, s + ns, cmp); sort(q, q + nq, cmp2); sort(A, A + sz); sz = unique(A, A + sz) - A; ps = 0, pq = 0; memset(c, 0, sizeof c); while (pq < nq) { if (ps == ns) get(); else { if (s[ps].x < q[pq].x) insert(); else if (s[ps].x > q[pq].x) get(); else { if (s[ps].f == 1) insert(); else get(); } } } for (int i = 0; i < nq; i++) printf("%d", ans[i]); printf("\n"); } return 0; }
时间: 2024-10-12 03:41:12