CDQ裸题,(x), (y), (tim)三维偏序
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("
----------
")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "
time: %.3fms
", clock() * 1000.0 / CLOCKS_PER_SEC)
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N= 2000007;
struct Ques{
int pos, tim, x, y, val, tag;
bool operator < (const Ques &com) const{
if(x != com.x) return x < com.x;
if(y != com.y) return y < com.y;
return tag < com.tag;
}
}q[N], tmp[N];
int t[N];
int n;
inline void Updata(int x, int w){
for(; x <= n; x += x & -x) t[x] += w;
}
inline int Query(int x){
int s = 0;
for(; x; x -= x & -x) s += t[x];
return s;
}
int ans[N];
inline void CDQ(int l, int r){
if(l == r) return;
int mid = (l + r) >> 1;
R(i,l,r){
if(q[i].tim <= mid && q[i].tag == 0){
Updata(q[i].y, q[i].val);
}
if(q[i].tim > mid && q[i].tag == 1){
ans[q[i].pos] += q[i].val * Query(q[i].y);
}
}
R(i,l,r){
if(q[i].tim <= mid && q[i].tag == 0){
Updata(q[i].y, -q[i].val);
}
}
int j = l, k = mid + 1;
R(i,l,r){
if(q[i].tim <= mid)
tmp[j++] = q[i];
else
tmp[k++] = q[i];
}
R(i,l,r){
q[i] = tmp[i];
}
CDQ(l, mid), CDQ(mid + 1, r);
}
int tot;
int main(){
freopen("1176.in", "r", stdin);
freopen("1176.out", "w", stdout);
int S;
io >> S >> n;
while(1){
int opt;
io >> opt;
if(opt == 3) break;
if(opt == 1){
++tot;
io >> q[tot].x >> q[tot].y >> q[tot].val;
q[tot].tim = tot;
}
else{
int X1, X2, Y1, Y2;
io >> X1 >> Y1 >> X2 >> Y2;
int pos = ++ans[0]; // pos is the order of the querys
ans[ans[0]] = S * (X2 - X1 + 1) * (Y2 - Y1 + 1);
q[++tot] = (Ques){ pos, tot, X1 - 1, Y1 - 1, 1, 1};
q[++tot] = (Ques){ pos, tot, X2, Y2, 1, 1};
q[++tot] = (Ques){ pos, tot, X1 - 1, Y2, -1, 1};
q[++tot] = (Ques){ pos, tot, X2, Y1 - 1, -1, 1};
}
}
sort(q + 1, q + tot + 1);
CDQ(1, tot);
R(i,1,ans[0]){
printf("%d
", ans[i]);
}
return 0;
}