luogu4390 [BOI2007]Mokia 摩基亚

刚入门cdq分治(入了吗),再研究研究orz

#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
int n, opt, xu, yu, xv, yv, ans[10005], cnt, c[2000005];
struct Node{
	int x, y, val, idx, pos, ans;
}q[200005], tmp[200005];
bool cmp(Node u, Node v){
	if(u.x!=v.x)	return u.x<v.x;
	else if(u.y!=v.y)	return u.y<v.y;
	else	return u.pos<v.pos;
}
int lb(int x){
	return x & -x;
}
void add(int p, int x){
	if(!p)	c[0] += x;
	else
		for(; p<=n; p+=lb(p))
			c[p] += x;
}
int query(int p){
	int re=c[0];
	for(; p; p-=lb(p))
		re += c[p];
	return re;
}
void cdq(int l, int r){
	if(l==r)	return ;
	int mid=(l+r)>>1;
	for(int i=l; i<=r; i++){
		if(q[i].idx<=mid && !q[i].pos)	add(q[i].y, q[i].val);
		if(q[i].idx>mid && q[i].pos)	q[i].ans += q[i].val * query(q[i].y);
	}
	for(int i=l; i<=r; i++)
		if(q[i].idx<=mid && !q[i].pos)
			add(q[i].y, -q[i].val);
	int jj=l, kk=mid+1;
	for(int i=l; i<=r; i++)
		if(q[i].idx<=mid)	tmp[jj++] = q[i];
		else	tmp[kk++] = q[i];
	for(int i=l; i<=r; i++)
		q[i] = tmp[i];
	cdq(l, mid); cdq(mid+1, r);
}
int main(){
	cin>>n;
	cin>>n;
	while(scanf("%d", &opt)!=EOF){
		if(opt==3)	break;
		if(opt==1){
			scanf("%d %d %d", &xu, &yu, &xv);
			cnt++; q[cnt] = (Node){xu, yu, xv, cnt, 0, 0};
		}
		else{
			scanf("%d %d %d %d", &xu, &yu, &xv, &yv);
			ans[0]++;
			cnt++; q[cnt] = (Node){xu-1, yu-1, 1, cnt, ans[0], 0};
			cnt++; q[cnt] = (Node){xu-1, yv, -1, cnt, ans[0], 0};
			cnt++; q[cnt] = (Node){xv, yu-1, -1, cnt, ans[0], 0};
			cnt++; q[cnt] = (Node){xv, yv, 1, cnt, ans[0], 0};
		}
	}
	sort(q+1, q+1+cnt, cmp);
	cdq(1, cnt);
	for(int i=1; i<=cnt; i++)
		if(q[i].pos)
			ans[q[i].pos] += q[i].ans;
	for(int i=1; i<=ans[0]; i++)
		printf("%d
", ans[i]);
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/8988902.html