BZOJ1176 [Balkan2007]Mokia(CDQ)

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("\n----------\n")
#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, "\ntime: %.3fms\n", 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\n", ans[i]);
	}
	return 0;
}
posted @ 2019-10-03 01:12  邱涵的秘密基地  阅读(194)  评论(0编辑  收藏  举报