cdq分治第一题。
最近的主题是数据结构,这玩意应该也算一种和莫队一样厉害的黑暗大法吧。有些需要你把在线写得足够厉害的题可以用这玩意来水。
写起来很像归并排序,按时间分治,然后再按某个坐标之类的玩意归并一下,归并的时候像求逆序对一样做,计算一边对另一边的贡献,顺便用点啥数据结构维护一下之类的。
这题有点像上帝造题七分钟。不过w的范围显然不是让你写二维树状数组。感觉那题可以用cdq水过,不过cdq好像不能用简单的二维树状数组,至少要动态一下啥的,然后空间就bye了。
这题就是按x排序查询y。课件上的原题。
另外依然不会迗代,还是写的递归。(找到了fft的感觉)
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long qw;
#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif
struct query {
int t, x, y, v;
inline query(int t0 = 0, int x0 = 0, int y0 = 0, int v0 = 0) {
t = t0, x = x0, y = y0, v = v0;
}
};
#define readInt(_s_) {\
int _d_;\
_s_ = 0;\
while (!isdigit(_d_ = getchar()));\
while ((_s_ = _s_ * 10 + _d_ - 48), isdigit(_d_ = getchar()));\
}
const int maxm = 2000009;
const int maxn = 200009;
qw ans[maxn], t[maxm];
int tmm[maxm], ttm;
int v0, m, n, q;
query a[maxn], b[maxn];
void btChg(int p, int v) {
for (++ p; p <= m; p += (p & -p))
if (tmm[p] < ttm)
tmm[p] = ttm, t[p] = v;
else
t[p] += v;
}
qw btQry(int p) {
qw s = 0;
for (++ p; p; p -= (p & -p))
if (tmm[p] < ttm)
tmm[p] = ttm, t[p] = 0;
else
s += t[p];
return s;
}
void cdq(int l, int r) {
if (l + 1 == r)
return;
int mid = (l + r) >> 1;
cdq(l, mid);
cdq(mid, r);
++ ttm;
for (int i = l, j = mid, k = l; i < mid || j < r;)
if (i < mid && (a[i]. x <= a[j]. x || j == r)) {
if (!a[i]. t)
btChg(a[i]. y, a[i]. v);
b[k ++] = a[i ++];
}
else {
if (a[j]. t) {
qw v = btQry(a[j]. y);
if (a[j]. t == 1)
ans[a[j]. v] += v;
else
ans[a[j]. v] -= v;
}
b[k ++] = a[j ++];
}
for (int i = l; i < r; ++ i)
a[i] = b[i];
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
memset(ans, 0, sizeof(ans));
memset(tmm, 0, sizeof(tmm));
ttm = 0;
readInt(v0);
readInt(m);
++ m;
n = 0;
q = 0;
while (1) {
int opt, x, y, u, v;
readInt(opt);
if (opt == 3)
break;
else if (opt == 2) {
readInt(x);
readInt(y);
readInt(u);
readInt(v);
-- x;
-- y;
a[n ++] = query(1, u, v, q);
a[n ++] = query(1, x, y, q);
a[n ++] = query(2, u, y, q);
a[n ++] = query(2, x, v, q);
ans[q] = (qw)v0 * (u - x) * (v - y);
++ q;
}
else {
readInt(x);
readInt(y);
readInt(v);
a[n ++] = query(0, x, y, v);
}
}
cdq(0, n);
for (int i = 0; i < q; ++ i)
printf("%d\n", (int)ans[i]);
}