[Balkan 2007] Mokia
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1176
[算法]
CDQ分治 + 树状数组即可
时间复杂度 : O(Nlog^2N)
[代码]
#include<bits/stdc++.h> using namespace std; const int N = 160010; const int M = 2000010; typedef long long ll; typedef long double ld; typedef unsigned long long ull; struct Query { int pos , x , y , value , type , id; } q[N * 5] , t1[N * 5] , t2[N * 5]; int s , w , m , k; int c[M] , ans[N]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline bool cmp(Query a , Query b) { if (a.x != b.x) return a.x < b.x; else if (a.y != b.y) return a.y < b.y; else return a.type < b.type; } inline int lowbit(int x) { return x & (-x); } inline void modify(int x , int val) { for (int i = x; i <= w; i += lowbit(i)) c[i] += val; } inline int query(int x) { int ret = 0; for (int i = x; i; i -= lowbit(i)) ret += c[i]; return ret; } inline void cdq(int l , int r) { int mid = (l + r) >> 1; if (l == r) return; for (int i = l; i <= r; i++) { if (q[i].type == 1 && q[i].pos <= mid) modify(q[i].y , q[i].value); else if (q[i].type == 2 && q[i].pos > mid) ans[q[i].id] += q[i].value * query(q[i].y); } for (int i = l; i <= r; i++) { if (q[i].type == 1 && q[i].pos <= mid) modify(q[i].y , -q[i].value); } int l1 = 0 , l2 = 0; for (int i = l; i <= r; i++) if (q[i].pos <= mid) t1[++l1] = q[i]; else t2[++l2] = q[i]; for (int i = 1; i <= l1; i++) q[l + i - 1] = t1[i]; for (int i = 1; i <= l2; i++) q[l + l1 + i - 1] = t2[i]; cdq(l , mid); cdq(mid + 1 , r); } int main() { read(s); read(w); while (true) { int type; read(type); if (type == 3) break; if (type == 1) { int x , y , a; read(x); read(y); read(a); q[++m] = (Query){m , x , y , a , 1 , k}; } else { int X1 , Y1 , X2 , Y2; read(X1); read(Y1); read(X2); read(Y2); ans[++k] = s * (X2 - X1 + 1) * (Y2 - Y1 + 1); q[++m] = (Query){m , X2 , Y2 , 1 , 2 , k}; q[++m] = (Query){m , X1 - 1 , Y2 , -1 , 2 , k}; q[++m] = (Query){m , X2 , Y1 - 1 , -1 , 2 , k}; q[++m] = (Query){m , X1 - 1 , Y1 - 1 , 1 , 2 , k}; } } sort(q + 1 , q + m + 1 , cmp); cdq(1 , m); for (int i = 1; i <= k; i++) printf("%d\n" , ans[i]); return 0; }