hdu-1255-覆盖的面积-线段树

Splay树的插入操作,只需要处理好插入节点的孩子节点就可以了,最重要的是不要破坏了BST的基本规则。

因为高度并不是Splay树的首要因素,所以插入的时候也是使用splay操作,然后在根节点插入。

参考:http://www.geeksforgeeks.org/splay-tree-set-2-insert-delete/

对比一下使用插入创建的树和手工创建数的区别,先序遍历的结果:

#pragma once
#include<stdio.h>
#include <stdlib.h>

class SplayTree_Insertion
{
	struct Node
	{
		int key;
		Node *left, *right;
		Node(int k) : key(k), left(NULL), right(NULL) {}
		~Node()
		{
			if (left) delete left, left = NULL;
			if (right) delete right, right = NULL;
		}
	};

	Node *rightRotate(Node *x)
	{
		Node *y = x->left;
		x->left = y->right;
		y->right = x;

		return y;
	}

	Node *leftRotate(Node *x)
	{
		Node *y = x->right;
		x->right = y->left;
		y->left = x;

		return y;
	}

	Node *splay(Node *root, const int key)
	{
		if (!root || key == root->key) return root;

		if (key < root->key)
		{
			if (!root->left) return root;

			if (key < root->left->key)
			{
				root->left->left = splay(root->left->left, key);
				root = rightRotate(root);//不应root->left
			}
			else if (root->left->key < key)
			{
				root->left->right = splay(root->left->right, key);
				if (root->left->right) root->left = leftRotate(root->left);
			}
			return root->left? rightRotate(root) : root;
		}
		if (!root->right) return root;
		if (root->right->key < key)
		{
			root->right->right = splay(root->right->right, key);
			root = leftRotate(root);
		}
		else if (key < root->right->key)
		{
			root->right->left = splay(root->right->left, key);
			if (root->right->left) root->right = rightRotate(root->right);
		}
		return root->right? leftRotate(root) : root;
	}

	Node *insert(Node *root, int k)
	{
		if (!root) return new Node(k);

		root = splay(root, k);

		if (root->key == k) return root;

		Node *newNode = new Node(k);

		//learn how to handle the insertion is the best way.
		if (k < root->key)
		{
			newNode->right = root;
			newNode->left = root->left;
			root->left = NULL;
		}
		else
		{
			newNode->left = root;
			newNode->right = root->right;
			root->right = NULL;
		}
		return newNode;
	}

	void preOrder(Node *root)
	{
		if (root != NULL)
		{
			printf("%d ", root->key);
			preOrder(root->left);
			preOrder(root->right);
		}
	}
public:
	SplayTree_Insertion()
	{
		Node *root = new Node(100);
		root->left = new Node(50);
		root->right = new Node(200);
		root->left->left = new Node(40);
		root->left->left->left = new Node(30);
		root->left->left->left->left = new Node(20);
		root = insert(root, 25);
		printf("Preorder traversal of the modified Splay tree is \n");
		preOrder(root);
		putchar('\n');

		delete root;

		runInsert();
	}

	void runInsert()
	{
		Node *root = NULL;
		int keys[] = {100, 50, 200, 40, 30, 20, 25};
		int n = sizeof(keys) / sizeof(keys[0]);
		for (int i = 0; i < n; i++)
		{
			root = insert(root, keys[i]);
		}

		printf("Inser create Preorder traversal Splay tree is \n");
		preOrder(root);
		putchar('\n');

		delete root;
	}
};

hdu-1255-覆盖的面积-线段树,布布扣,bubuko.com

时间: 2024-08-26 17:59:41

hdu-1255-覆盖的面积-线段树的相关文章

hdu 1255 覆盖的面积(线段树&amp;扫描线&amp;重复面积)

覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3375    Accepted Submission(s): 1645 Problem Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数

hdu 1255 覆盖的面积 线段树扫描线求重叠面积

稀里糊涂打完了没想到1A了,心情还是很舒畅的,c和c++的四舍五入还是四舍六入遇积进位遇偶舍,我感觉很混乱啊,这道题我输出的答案是7.62,也就是遇偶舍了,可是我就手动处理一下进位问题,发现0.005 系统自动进位0.01了,尼玛啊,我一下子就混乱了,不是遇偶舍么,0也是偶数啊,怎么就进位了呢.最后我就不手动处理进位问题了,直接0.2lf%,虽然我输出的结果是7.62,但是提交也过了 这道题和poj1151,hdu1542差不多,扫描线详细讲解http://blog.csdn.net/young

HDU 1255 覆盖的面积 (线段树+扫描线+离散化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 题意很清楚,就是让你求矩阵之间叠加层数大于1的矩形块的面积和. 因为n只有1000,所以我离散化一下,数据大小就缩小了,那么之后只需要线段树单点更新就好了. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <map> 5 #include <algor

HDU 1255 覆盖的面积(线段树面积并)

描述 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数据的第一行是一个正整数N(1<=N<=1000),代表矩形的数量,然后是N行数据,每一行包含四个浮点数,代表平面上的一个矩形的左上角坐标和右下角坐标,矩形的上下边和X轴平行,左右边和Y轴平行.坐标的范围从0到100000. 注意:本题的输入数据较多,推荐使用scanf读入数据. Output 对于每组测试数据,请计算出

HDU 1255 覆盖的面积 (线段树 + 离散化 + 扫描线)

覆盖的面积 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4304    Accepted Submission(s): 2139 Problem Description 给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. Input 输入数据的第一行是一个正整数T(1<=T<=100),代表测试数据的数量.每个测试数

HDU 1255 覆盖的面积 线段树+扫描线

同 POJ1151 这次是两次 #include <iostream> #include <algorithm> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #include <vector

HDU 1255 覆盖的面积 (扫描线 线段树 离散化)

题目链接 题意:中文题意. 分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt>=0改成cnt>=2就行了,. 但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了,因为虽然现在都不等于 2,但是之前的那个线段加上现在的已经覆盖2次了. 1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include &

hdu 1255 覆盖的面积(扫描线)

http://acm.hdu.edu.cn/showproblem.php?pid=1255 一道挺简单的题,让我折腾了许久.主要卡在了更新节点后维护父亲节点上.后来思路明确了就很容易了. 节点信息: l,r:区间端点 cnt:区间被覆盖的次数,cnt = 0说明没有被完全覆盖. len1:区间被覆盖的长度 len2:区间至少被两条线段覆盖的长度. 只要找到父亲节点与子节点在len1,len2,cnt的关系就简单了. #include <stdio.h> #include <iostre

hdu 1255 覆盖的面积

http://acm.hdu.edu.cn/showproblem.php?pid=1255 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 100010 5 using namespace std; 6 7 int t,n; 8 double Y[maxn],X[maxn]; 9 struct point 10 { 11 double x; 12 double

hdu(1255)——覆盖的面积(线段树求面积交)

给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 虽说覆盖两次区域的面积,但是这道题实际上就是求矩形的面积交. 膜拜能够想出这种解法的神牛,竟然能把实际的东西用这么抽象的语言表示出来,实在是佩服,现在关于扫描线的题才做了几道,没有对其深刻理解,但是多练总可以理解的,奋斗吧!!ACMer!!我是永远不会服输的.加油! 下面还是附上题解,写的不够详细清楚还请多多见谅. 首先我想说我是看了别人的博客学了思路,然后按照别人的代码来模仿写的. 这里推荐:http://www.cnblogs.