题目链接:点击打开链接
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;
}