BZOJ 1176: [Balkan2007]Mokia【CDQ分治+树状数组

80 篇文章 0 订阅
4 篇文章 0 订阅

CDQ裸题,和2683基本一样……于是我就naive地直接粘了根本没看题……GG

#include<bits/stdc++.h>
#define MAXA 200005
#define MAXT 2000006
using namespace std;	int N,S;
inline int read(){
	register char ch = getchar();
	while((ch^'-')&&!isdigit(ch))	ch = getchar();
	register int rtn = 0 , f = 1;
	if(ch == '-')	f = -1 , ch = getchar();
	while(isdigit(ch))	rtn = rtn*10 + ch - '0' , ch = getchar();
	return f*rtn;
}
//===========
int ans[MAXA] , ned[MAXA] , cnt_ans;


struct t1{
	int typ;
	int x,y;
	int A;
	int out_id;
	t1(){}
	t1(int typ,int x,int y,int A,int out_id):
		typ(typ),x(x),y(y),A(A),out_id(out_id){}
	inline bool operator < (const t1 &ano) const{
		if(x==ano.x){
			if(!typ)	return 1;
			if(!ano.typ)	return 0;
			return 0;
		}
		return x < ano.x;
	}
}rec[MAXA] , tmp[MAXA];	int cnt_rec , cnt_tmp;

int sum[MAXT];
inline void add(int pos,int x){
	for(int i=pos;i<=N;i += i&-i)
		sum[i] += x;
}
inline int ask(int pos){
	int rtn = 0;
	for(int i=pos;i;i -= i&-i)
		rtn += sum[i];
	return rtn;
}
//==============

void CDQ(int l,int r){
	if(l==r)	return ;
	int mid = (l+r)>>1;
	
	cnt_tmp = 0;
	for(int i=l;i<=mid;++i)	if(!rec[i].typ)	tmp[++cnt_tmp] = rec[i];
	for(int i=mid+1;i<=r;++i)	if(rec[i].typ!=0)	tmp[++cnt_tmp] = rec[i];

	sort(tmp+1,tmp+cnt_tmp+1);

	for(int i=1;i<=cnt_tmp;++i){
		if(!tmp[i].typ)
			add(tmp[i].y,tmp[i].A);
		else	ans[tmp[i].out_id] += tmp[i].typ * ask(tmp[i].y);
	}
	for(int i=1;i<=cnt_tmp;++i)
		if(!tmp[i].typ)	add(tmp[i].y,-tmp[i].A);
	CDQ(l,mid) , CDQ(mid+1,r);
}

int main(){
//	freopen("1.in","r",stdin);
	S = read() , N = read()+1;

	for(int opt = read();opt^3;opt = read()){
		ans[++cnt_ans];
		if(opt==1){
			ned[cnt_ans] = 0;
			int a = read()+1 , b = read()+1 , c =read();
			rec[++cnt_rec] = t1(0,a,b,c,cnt_ans);
		
		}else{
			ned[cnt_ans] = 1;
			int a = read()+1 , b = read()+1 , c = read()+1 , d = read()+1;
			ans[cnt_ans] = S * (c-a+1)*(d-b+1);
			rec[++cnt_rec] = t1(1,a-1,b-1,0,cnt_ans);
			rec[++cnt_rec] = t1(1,c,d,0,cnt_ans);
			rec[++cnt_rec] = t1(-1,a-1,d,0,cnt_ans);
			rec[++cnt_rec] = t1(-1,c,b-1,0,cnt_ans);
		}
	}
	CDQ(1,cnt_rec);
	for(int i=1;i<=cnt_ans;++i)
		if(ned[i])	printf("%d\n",ans[i]);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值