线段树



POJ 3264 模板题目

#include<stdio.h>
#include<algorithm>
using namespace std;

const int INF = 1 << 30;

int minV = INF;
int maxV = -INF;

struct Node
{
	int maxV;
	int minV;
	int L, R;
	int mid()
	{
		return (L + R) / 2;
	}
};

Node tree[800010];

void buildTree(int root, int L, int R)
{
	tree[root].L = L;
	tree[root].R = R;
	tree[root].maxV = -INF;
	tree[root].minV = INF;
	if (L != R)
	{
		buildTree(2 * root + 1, L, (L + R) / 2);
		buildTree(2 * root + 2, (L + R) / 2 + 1, R);
	}
}

void insert(int root, int i, int v)
{
	if (tree[root].L == tree[root].R)
	{
		tree[root].minV = tree[root].maxV=v;
		return;
	}
	tree[root].minV = min(tree[root].minV, v);
	tree[root].maxV = max(tree[root].maxV, v);

	if (i <= tree[root].mid())
		insert(2 * root + 1, i, v);
	else
		insert(2 * root + 2, i, v);
}

void query(int root, int s, int e)
{
	if (tree[root].minV >= minV && tree[root].maxV <= maxV)
		return;
	if (tree[root].L == s && tree[root].R == e)
	{
		minV = min(minV, tree[root].minV);
		maxV = max(maxV, tree[root].maxV);
		return;
	}
	if (e <= tree[root].mid())
		query(2 * root + 1, s, e);
	else if (s>tree[root].mid())
		query(2 * root + 2, s, e);
	else
	{
		query(2 * root + 1, s, tree[root].mid());
		query(2 * root + 2, tree[root].mid() + 1, e);
	}
}

int main()
{
	int n, q, h;
	

	scanf("%d%d", &n, &q);
	buildTree(0, 1, n);

	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &h);
		insert(0, i, h);
	}
	for (int i = 0; i<q; i++)
	{
		int s, e;
		scanf("%d%d", &s, &e);
		minV = INF;
		maxV = -INF;
		query(0, s, e);
		printf("%d\n", maxV - minV);
	}
}





POJ 3468 模板题2

#include<stdio.h>
#include<algorithm>
using namespace std;

struct CNode
{
	int L, R;
	CNode *left,* right;
	long long nsum;
	long long lnc;
	int mid()
	{
		return (L + R) / 2;
	}
};

CNode Tree[200010];
int nCount = 0;

void buildTree(CNode * pRoot, int L, int R)
{
	pRoot->L = L;
	pRoot->R = R;
	pRoot->nsum = 0;
	pRoot->lnc = 0;
	if (L == R)
		return;
	nCount++;
	pRoot->left = Tree + nCount;
	nCount++;
	pRoot->right = Tree + nCount;
	buildTree(pRoot->left, L, (L + R) / 2);
	buildTree(pRoot->right, (L + R) / 2 + 1, R);
}

void insert(CNode* pRoot, int i, int v)
{
	if (pRoot->L == i && pRoot->R == i)
	{
		pRoot->nsum = v;
		return;
	}
	pRoot->nsum += v;
	if (i <= pRoot->mid())
		insert(pRoot->left, i, v);
	else
		insert(pRoot->right, i, v);

}

void add(CNode * pRoot, int a, int b, long long c)
{
	if (pRoot->L == a && pRoot->R == b)
	{
		pRoot->lnc += c;
		return;
	}
	pRoot->nsum+=(b-a+1)*c;
	if (b <= pRoot->mid())
		add(pRoot->left, a, b, c);
	else if (a>pRoot->mid())
		add(pRoot->right, a, b, c);
	else
	{
		add(pRoot->left, a, pRoot->mid(), c);
		add(pRoot->right, pRoot->mid()+1, b, c);
	}
}

long long querySum(CNode* pRoot, int a, int b)
{
	if (pRoot->L == a && pRoot->R == b)
	{
		return pRoot->nsum + (pRoot->R - pRoot->L + 1)*pRoot->lnc;
	}
	pRoot->nsum += (pRoot->R - pRoot->L + 1)*pRoot->lnc;
	add(pRoot->left, pRoot->L, pRoot->mid(), pRoot->lnc);
	add(pRoot->right, pRoot->mid()+1, pRoot->R, pRoot->lnc);
	pRoot->lnc = 0;

	if (b <= pRoot->mid())
		return querySum(pRoot->left, a, b);
	else if (a>pRoot->mid())
		return querySum(pRoot->right, a, b);
	else
	{
		return querySum(pRoot->left, a, pRoot->mid()) + querySum(pRoot->right, pRoot->mid() + 1, b);
	}
}


int main()
{
	int n, q, a, b, c;
	char cmd[10];
	scanf("%d%d", &n, &q);
	nCount = 0;
	buildTree(Tree, 1, n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &a);
		insert(Tree, i, a);
	}
	for (int i = 0; i<q; i++)
	{
		scanf("%s", cmd);
		if (cmd[0] == 'C')
		{
			scanf("%d%d%d", &a, &b, &c);
			add(Tree, a, b, c);
		}
		else
		{
			scanf("%d%d", &a, &b);
			printf("%lld\n", querySum(Tree, a, b));
		}
	}
}




POJ 2528 海报张贴

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;

struct Node
{
	int l, r;
	bool iscovered;//Full coverage
	int left, right;
	int mid()
	{
		return (l + r) / 2;
	}
};

Node tree[50000];

struct Poster
{
	int l, r;
};

Poster poster[10010];
int sortArr[20020];
int hashArr[10000010];

int n;
int cnt;

void buildTree(int root, int a, int b)
{
	tree[root].iscovered = false;
	tree[root].l = a;
	tree[root].r = b;
	if (a == b)
		return;
	tree[root].left = 2 * root + 1;
	tree[root].right = 2 * root + 2;
	buildTree(tree[root].left, a, tree[root].mid());
	buildTree(tree[root].right, tree[root].mid() + 1, b);
}


bool insert(int root, int a, int b)//1 ,wan quan fu gai
{
	if (tree[root].iscovered == true)
		return true;

	if (tree[root].l == a &&  tree[root].r == b)
	{
		tree[root].iscovered = true;
		return false;
	}
	bool result;
	if (b <= tree[root].mid())
		result = insert(tree[root].left, a, b);
	else if (a>tree[root].mid())
		result = insert(tree[root].right, a, b);
	else
	{

		bool result1 = insert(tree[root].left, a, tree[root].mid());
		bool result2 = insert(tree[root].right, tree[root].mid() + 1, b);
		result = result1&&result2;
	}
	if (tree[tree[root].left].iscovered == true && tree[tree[root].right].iscovered == true)
		tree[root].iscovered = true;
	return result;
}

int main()
{
	int c;
	scanf("%d", &c);

	while (c--)
	{
		scanf("%d", &n);
		cnt = 0;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d%d", &poster[i].l, &poster[i].r);
			sortArr[cnt++] = poster[i].l;
			sortArr[cnt++] = poster[i].r;
		}
		sort(sortArr, sortArr + cnt);
		cnt = unique(sortArr, sortArr + cnt) - sortArr;
		memset(hashArr, -1, sizeof(hashArr));
		for (int i = 0; i<cnt; i++)
		{
			hashArr[sortArr[i]] = i;
		}
		buildTree(0, 0, cnt);

		int ans = 0;
		for (int i = n; i >= 1; i--)
		{
			if (!insert(0, hashArr[poster[i].l], hashArr[poster[i].r]))
				ans++;
		}
		printf("%d\n", ans);
	}
}







POJ 1151 矩形面积(区间两头的点)

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;

const int MAXN = 110;

map<double, int> yMap;

struct Node
{
	double len;
	int cover;

	int l, r;
};

struct Line
{
	double x, y1, y2;
	bool isLeft;
	bool operator<(const Line & rhs)const
	{
		return x<rhs.x;
	}
};

Node tree[MAXN * 5];
Line lines[MAXN * 2];

int n, cnt;
double y[MAXN * 2];

void build(int root, int l, int r)
{
	tree[root].l = l;
	tree[root].r = r;
	tree[root].len = 0;
	tree[root].cover = 0;
	if (r > l + 1)
	{
		build(2 * root, l, (l + r) / 2);
		build(2 * root + 1, (l + r) / 2, r);
	}
}

void insert(int root, int l, int r)
{
	if (tree[root].l == l && tree[root].r == r)
	{
		tree[root].cover++;
		tree[root].len = y[r] - y[l];
		return;
	}

	int mid = (tree[root].l + tree[root].r) / 2;
	if (r <= mid)
		insert(2 * root, l, r);
	else if (l >= mid)
		insert(2 * root + 1, l, r);
	else
	{
		insert(2 * root, l, mid);
		insert(2 * root + 1, mid, r);
	}

	if (tree[root].cover == 0)
	{
		tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
		
	}

}

void del(int root, int l, int r)
{
	if (tree[root].l == l && tree[root].r == r)
	{
		tree[root].cover--;
		if (tree[root].cover == 0)
		{
			if (tree[root].r - tree[root].l > 1)
				tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
			else
				tree[root].len = 0;
		}
		return;
	}
	else
	{
		int mid = (tree[root].l + tree[root].r) / 2;
		if (r <= mid)
			del(2 * root, l, r);
		else if (l >= mid)
			del(2 * root + 1, l, r);
		else
		{
			del(2 * root, l, mid);
			del(2 * root + 1, mid, r);
		}
	}
	if (tree[root].cover == 0)
	{
		tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
	}
}



int main()
{
	int t = 1;
	while (true)
	{
		yMap.clear();
		double x1, x2, y1, y2;
		scanf("%d", &n);
		if (n == 0)
			return 0;
		for (int i = 0; i < n; i++)
		{
			scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
			lines[2 * i].x = x1;
			lines[2 * i + 1].x = x2;
			lines[2 * i].y1 = lines[2 * i + 1].y1 = y1;
			lines[2 * i].y2 = lines[2 * i + 1].y2 = y2;
			lines[2 * i].isLeft = true;
			lines[2 * i + 1].isLeft = false;
			y[2 * i] = y1;
			y[2 * i + 1] = y2;
		}
		sort(y, y + 2 * n);
		cnt = unique(y, y + 2 * n) - y;
		for (int i = 0; i < cnt; i++)
			yMap[y[i]] = i;


		sort(lines, lines + 2 * n);
		build(1, 0, cnt - 1);
		double ans = 0;
		for (int i = 0; i < 2 * n - 1; i++)
		{
			if (lines[i].isLeft)
				insert(1, yMap[lines[i].y1], yMap[lines[i].y2]);
			else
				del(1, yMap[lines[i].y1], yMap[lines[i].y2]);
			ans += tree[1].len*(lines[i + 1].x - lines[i].x);

		}
		printf("Test case #%d\nTotal explored area: %.2f\n\n", t++, ans);
	}
}



POJ 1151 矩形面积(区间)

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;

const int MAXN = 110;

map<double, int> yMap;

struct Node
{
	double len;
	int cover;

	int l, r;
};

struct Line
{
	double x, y1, y2;
	bool isLeft;
	bool operator<(const Line & rhs)const
	{
		return x < rhs.x;
	}
};

Node tree[MAXN * 5];
Line lines[MAXN * 2];

int n, cnt;
double y[MAXN * 2];

void build(int root, int l, int r)
{
	tree[root].l = l;
	tree[root].r = r;
	tree[root].len = 0;
	tree[root].cover = 0;
	if (r != l)
	{
		build(2 * root, l, (l + r) / 2);
		build(2 * root + 1, (l + r) / 2 + 1, r);
	}
}

void insert(int root, int l, int r)
{
	if (tree[root].l == l && tree[root].r == r)
	{
		tree[root].cover++;
		tree[root].len = y[r + 1] - y[l];
		return;
	}

	int mid = (tree[root].l + tree[root].r) / 2;
	if (r <= mid)
		insert(2 * root, l, r);
	else if (l >= mid+1)
		insert(2 * root + 1, l, r);
	else
	{
		insert(2 * root, l, mid);
		insert(2 * root + 1, mid + 1, r);
	}

	if (tree[root].cover == 0)
	{
		tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;

	}

}

void del(int root, int l, int r)
{
	if (tree[root].l == l && tree[root].r == r)
	{
		tree[root].cover--;
		if (tree[root].cover == 0)
		{
			if (tree[root].r != tree[root].l)
				tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
			else
				tree[root].len = 0;
		}
		return;
	}
	else
	{
		int mid = (tree[root].l + tree[root].r) / 2;
		if (r <= mid)
			del(2 * root, l, r);
		else if (l >= mid+1)
			del(2 * root + 1, l, r);
		else
		{
			del(2 * root, l, mid);
			del(2 * root + 1, mid + 1, r);
		}
	}
	if (tree[root].cover == 0)
	{
		tree[root].len = tree[2 * root].len + tree[2 * root + 1].len;
	}
}



int main()
{
	int t = 1;
	while (true)
	{
		yMap.clear();
		double x1, x2, y1, y2;
		scanf("%d", &n);
		if (n == 0)
			return 0;
		for (int i = 0; i < n; i++)
		{
			scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
			lines[2 * i].x = x1;
			lines[2 * i + 1].x = x2;
			lines[2 * i].y1 = lines[2 * i + 1].y1 = y1;
			lines[2 * i].y2 = lines[2 * i + 1].y2 = y2;
			lines[2 * i].isLeft = true;
			lines[2 * i + 1].isLeft = false;
			y[2 * i] = y1;
			y[2 * i + 1] = y2;
		}
		sort(y, y + 2 * n);
		cnt = unique(y, y + 2 * n) - y;
		for (int i = 0; i < cnt; i++)
			yMap[y[i]] = i;


		sort(lines, lines + 2 * n);
		build(1, 0, cnt - 1 - 1);
		double ans = 0;
		for (int i = 0; i < 2 * n - 1; i++)
		{
			if (lines[i].isLeft)
				insert(1, yMap[lines[i].y1], yMap[lines[i].y2]-1);
			else
				del(1, yMap[lines[i].y1], yMap[lines[i].y2]-1);
			ans += tree[1].len*(lines[i + 1].x - lines[i].x);

		}
		printf("Test case #%d\nTotal explored area: %.2f\n\n", t++, ans);
	}
}




POJ 3321 苹果树 树状数组

#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std;

#define MAXN 100010

vector<vector<int> > graph(100010);

int start[MAXN];
int End[MAXN];
int c[MAXN * 2];

int n;

int ncount;
int lowBit[MAXN*2];
int hasApple[MAXN];

void dfs(int u)
{
	start[u] = ++ncount;
	for (int i = 0; i<graph[u].size(); i++)
	{
		dfs(graph[u][i]);
	}
	End[u] = ++ncount;
}



void modify(int num, int val)
{
	while (num <= ncount)
	{
		c[num] += val;
		num += lowBit[num];
	}
}

int query(int num)
{
	int sum = 0;
	while (num>0)
	{
		sum += c[num];
		num -= lowBit[num];
	}
	return sum;
}

int main()
{
	scanf("%d", &n);
	int u, v;
	ncount = 0;




	for (int i = 0; i<MAXN; i++)
		hasApple[i] = 1;


	for (int i = 0; i<n - 1; i++)
	{
		scanf("%d%d", &u, &v);
		graph[u].push_back(v);
	}

	dfs(1);

	for (int i = 0; i <= ncount; i++)
		lowBit[i] = (i&(-i));

	for (int i = 0; i <= ncount; i++)
		c[i] = i - (i - lowBit[i]);

	int m;
	scanf("%d", &m);

	char cmd[5];

	int a;

	for (int i = 0; i<m; i++)
	{
		scanf("%s%d", cmd, &a);
		if (cmd[0] == 'C')
		{
			if (hasApple[a])
			{
				hasApple[a] = 0;
				modify(start[a], -1);
				modify(End[a], -1);
			}
			else
			{
				hasApple[a] = 1;
				modify(start[a], 1);
				modify(End[a], 1);
			}
		}
		else
		{
			int t1 = query(start[a] - 1);
			int t2 = query(End[a]);
			printf("%d\n", (t2 - t1) / 2);
		}
	}


}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值