用四分树写MLE了,有什么优化技巧吗

#ifdef debug
#include <time.h>
#include "/home/majiao/mb.h"
#endif


#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <map>
#include <queue>
#define MAXN ((int)2e4+7)
#define ll long long int
#define QAQ (0)
using namespace std;

int n, sz;
int x, y, val;
int x1, x2, Y1, y2;

struct Node { //四分树
	int x1, x2, Y1, y2, sum;
	Node(int _x1=1, int _x2=1024, int _Y1=1, int _y2=1024) :
		x1(_x1), x2(_x2), Y1(_Y1), y2(_y2), sum(0) { }
	Node* chl[4]; //横竖切分成四个块a,b,c,d

	inline bool inRect(int a, int b, int c, int d) { //判断该节点的矩形是否完全在矩形(abcd)里
		return this->x1 >= a && this->x2 <= b
			&& this->Y1 >= c && this->y2 <= d;
	}
	inline bool havIntersect(int a, int b, int c, int d) { //判断两矩形(该节点的矩形和矩形abcd)是否有交集
		int maxw = max(x2, b);
		int maxh = max(y2, d);
		int minw = min(x1, a);
		int minh = min(Y1, c);
		int w1 = x2 - x1, w2 = b - a;
		int h1 = y2 - Y1, h2 = d - c;
		if(maxw-minw <= w1+w2 && maxh-minh <= h1+h2) return true;
		return false;
	}
#ifdef debug
	friend ostream& operator << (ostream& out, Node& node) {
		out << "[" << node.x1 << "," << node.x2 << "," << node.Y1 << "," <<
			node.y2 << "]" << endl;
		return out;
	}
#endif
} root;

void insert(Node* now) { //插入一个值
//	now->sum += val;
	if(now->x1 == now->x2 && now->Y1 == now->y2) {
		now->sum = !now->sum;
		return ;
	}
	now->sum = 0;

	int midx = (now->x1 + now->x2) >> 1, midy = (now->Y1 + now->y2) >> 1;
	if(x>=now->x1 && x<=midx && y>=now->Y1 && y<=midy) { //左上
		if(!now->chl[0])
			now->chl[0] = new Node(now->x1, midx, now->Y1, midy);
		insert(now->chl[0]);
	}
	if(x>=midx+1 && x<=now->x2 && y>=now->Y1 && y<=midy) { //右上
		if(!now->chl[1])
			now->chl[1] = new Node(midx+1, now->x2, now->Y1, midy);
		insert(now->chl[1]);
	}
	if(x>=now->x1 && x<=midx && y>=midy+1 && y<=now->y2) { //左下
		if(!now->chl[2])
			now->chl[2] = new Node(now->x1, midx, midy+1, now->y2);
		insert(now->chl[2]);
	}
	if(x>=midx+1 && x<=now->x2 && y>=midy+1 && y<=now->y2) { //右下
		if(!now->chl[3])
			now->chl[3] = new Node(midx+1, now->x2, midy+1, now->y2);
		insert(now->chl[3]);
	}
	for(int i=0; i<4; i++)
		if(now->chl[i]) now->sum += now->chl[i]->sum;
}

int query(Node* now) { //查询矩形(x1,Y1,x2,y2)里的和
	//先判空 两个矩形有交集才往下递归
	if(!now || !now->havIntersect(x1, x2, Y1, y2)) return 0;

	//如果这个节点的矩形完全被包含在被查询的矩形里 就直接返回这个节点的和
	if(now->inRect(x1, x2, Y1, y2)) return now->sum;
	int ret = 0;
	for(int i=0; i<4; i++) //如果不完全包含就递归4个子树
		if(now->chl[i] && now->chl[i]->havIntersect(x1, x2, Y1, y2))
			ret += query(now->chl[i]);
	return ret;
}

int main() {
#ifdef debug
	freopen("test", "r", stdin);
	clock_t stime = clock();
#endif
	int m;
	scanf("%d %d ", &n, &m);
	for(int i=1; i<=n; i++)
		for(int k=1; k<=n; k++) {
			scanf("%d ", &val);
			x = i, y = k;
			if(val)
				insert(&root);
		}
	while(m--) {
		int op;
		scanf("%d ", &op);
		if(op == 1) {
			scanf("%d %d ", &x, &y);
			insert(&root);
		} else {
			scanf("%d %d %d %d ", &x1, &Y1, &x2, &y2);
//			printf("%d %d %d %d   ", x1, Y1, x2, y2);
			int ans = query(&root);
			printf("%d\n", ans);
		}
	}







#ifdef debug
	clock_t etime = clock();
	printf("rum time: %lf 秒\n",(double) (etime-stime)/CLOCKS_PER_SEC);
#endif
	return 0;
}


全部评论
 四分树复杂度不太对吧
点赞 回复 分享
发布于 2020-04-28 15:51

相关推荐

牛油果甜奶昔:别的先不说,牛客还能内推护士?
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务