题目链接:点击打开链接
cdq入门资料:点击打开链接
思路:首先根据上面的ppt可知cdq分治:
solve(l, mid);
计算[l,mid] 对 [mid+1, r] 区间的影响
solve(mid+1, r);
计算影响部分,把询问拆成2个,对x排序后搞搞即可。
#include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <string.h> #include <limits.h> #include <vector> #include <string> #include <time.h> #include <math.h> #include <queue> #include <stack> #include <set> #include <map> const double eps = 1e-8; const double pi = acos(-1.0); template <class T> inline bool rd(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void pt(T x) { if (x <0) { putchar('-'); x = -x; } if (x>9) pt(x / 10); putchar(x % 10 + '0'); } using namespace std; typedef long long ll; int c[500005], maxn; inline int Lowbit(int x){ return x&(-x); } void add(int i, int x){ while (i <= maxn) c[i] += x,i += Lowbit(i); } int sum(int x){//区间求和 [1,x] int ans = 0; for (int i = x; i ; i -= Lowbit(i)) ans += c[i]; return ans; } const int N = 200005; struct Q{ int op, x1, y1, x2, y2, z, num, ans; }q[N], cc[N<<1]; bool cmp(const Q&x, const Q&y){ if (x.x1 == y.x1)return x.op < y.op; return x.x1 < y.x1; } int w, n; int top; void solve(int l, int r){ if (l == r)return; int mid = (l + r) >> 1; top = 0; for (int i = l; i <= mid; i++)if (q[i].op == 1)cc[top++] = q[i]; for (int i = mid + 1; i <= r; i++){ if (q[i].op == 2){ cc[top++] = q[i]; cc[top++] = q[i]; cc[top - 2].x1--; cc[top - 1].x1 = q[i].x2; cc[top - 1].op = 3; } } sort(cc, cc + top, cmp); for (int i = 0; i < top; i++){ if (cc[i].op == 1) add(cc[i].y1, cc[i].z); else if (cc[i].op == 2) q[cc[i].num].ans -= sum(cc[i].y2) - sum(cc[i].y1 - 1); else q[cc[i].num].ans += sum(cc[i].y2) - sum(cc[i].y1 - 1); } for (int i = 0; i < top; i++) if (cc[i].op == 1) add(cc[i].y1, -cc[i].z); solve(l, mid); solve(mid + 1, r); } int main(){ freopen("locust.in", "r", stdin); freopen("locust.out", "w", stdout); rd(w); rd(n); maxn = w; for (int i = 1, x1, y1, x2, y2; i <= n; i++){ q[i].num = i; rd(q[i].op); if (q[i].op == 1){ rd(q[i].x1); rd(q[i].y1); rd(q[i].z); } else { rd(x1); rd(y1); rd(x2); rd(y2); q[i].x1 = min(x1, x2); q[i].y1 = min(y1, y2); q[i].x2 = max(x1, x2); q[i].y2 = max(y1, y2); } } solve(1, n); for (int i = 1; i <= n; i++) if (q[i].op == 2)pt(q[i].ans), putchar('\n'); return 0; }
原文:http://blog.csdn.net/qq574857122/article/details/45623067