记录编号 95569 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [OIBH 练习赛#6]战地统计系统 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 3.609 s
提交时间 2014-04-07 19:04:12 内存使用 78.17 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int SIZEN=1010,SIZEM=2010;
class NODE{
public:
	int x1,y1,x2,y2;//左下角和右上角,包含整个闭区间
	int size;
	int lc,rc;//左右儿子
	int lazy;
	bool clr;//是否被清除,这个排在lazy前面,切记不能用sum判断是否清空
	int sum;//部队数量,如果是0代表该区域已清空
	//clear可以清空lazy,反之不行
	void clear(void){sum=lazy=0;clr=true;}
};
NODE tree[SIZEN*SIZEN*2];
int tot=0;
int build(int x1,int y1,int x2,int y2){
	int p=tot++;
	NODE &now=tree[p];
	now.x1=x1,now.y1=y1,now.x2=x2,now.y2=y2;
	now.size=(x2-x1+1)*(y2-y1+1);
	now.lazy=now.clr=now.sum=0;
	if(x1<x2||y1<y2){
		if(x2-x1>=y2-y1){
			int xm=(x1+x2)/2;
			now.lc=build(x1,y1,xm,y2);
			now.rc=build(xm+1,y1,x2,y2);
		}
		else{
			int ym=(y1+y2)/2;
			now.lc=build(x1,y1,x2,ym);
			now.rc=build(x1,ym+1,x2,y2);
		}
	}
	else now.lc=now.rc=-1;
	return p;
}
void update(int root){
	if(root==-1) return;
	NODE &now=tree[root];
	if(now.lc==-1){
		now.clr=(!now.sum);
		return;
	}
	NODE &lson=tree[now.lc],&rson=tree[now.rc];
	now.sum=lson.sum+rson.sum;
	//两个lazy标记都不能update
}
void pushdown(int root){
	if(root==-1) return;
	NODE &now=tree[root];
	if(now.lc==-1) return;
	NODE &lson=tree[now.lc],&rson=tree[now.rc];
	if(now.clr){//清空,这个操作先于lazy
		lson.clear();
		rson.clear();
		now.clr=false;
	}
	if(now.lazy){
		NODE &lson=tree[now.lc],&rson=tree[now.rc];
		lson.lazy+=now.lazy,rson.lazy+=now.lazy;
		lson.sum+=now.lazy*lson.size,rson.sum+=now.lazy*rson.size;
		now.lazy=0;
	}
}
int fire(int root,int x1,int y1,int x2,int y2){//返回区域内军队数量,并把它们干掉
	pushdown(root);
	NODE &now=tree[root];
	if(now.x1>x2||now.x2<x1||now.y1>y2||now.y2<y1) return 0;
	if(now.x1>=x1&&now.x2<=x2&&now.y1>=y1&&now.y2<=y2){
		int ans=now.sum;
		now.clear();//之前的lazy必须清除
		return ans;
	}
	else{
		int ans=fire(now.lc,x1,y1,x2,y2)+fire(now.rc,x1,y1,x2,y2);
		update(root);
		return ans;
	}
}
void add(int root,int x1,int y1,int x2,int y2,int t){//范围内每格加t
	pushdown(root);
	NODE &now=tree[root];
	if(now.x1>x2||now.x2<x1||now.y1>y2||now.y2<y1) return;
	if(now.x1>=x1&&now.x2<=x2&&now.y1>=y1&&now.y2<=y2){
		now.lazy+=t;
		now.sum+=t*now.size;
	}
	else{
		add(now.lc,x1,y1,x2,y2,t);
		add(now.rc,x1,y1,x2,y2,t);
		update(root);
	}
}
int N,M,maxV=0;
int K[SIZEM]={0},X1[SIZEM]={0},X2[SIZEM]={0},V[SIZEM]={0};
void work(void){
	for(int i=1;i<=M;i++){
		if(K[i]==1){//增援
			add(0,X1[i],1,X2[i],V[i],1);
		}
		else{
			printf("%d\n",fire(0,X1[i],1,X2[i],V[i]));
		}
	}
}
void init(void){
	scanf("%d%d",&N,&M);
	for(int i=1;i<=M;i++){
		scanf("%d%d%d%d",&K[i],&X1[i],&X2[i],&V[i]);
		maxV=max(maxV,V[i]);
	}
	build(1,1,N,maxV);
}
int main(){
	freopen("battlefieldstat.in","r",stdin);
	freopen("battlefieldstat.out","w",stdout);
	init();
	work();
	return 0;
}