poj 2528

二维离散化+区间线段树

#include <iostream>
#include <cstdio>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <stack>

#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define l(x) ((x)<<1)
#define r(x) ((x)<<1|1)
#define lowbit(x) ((x)&(-(x)))
#define abs(x) ((x)>=0?(x):(-(x)))
#define ms(a,b) memset(a,b,sizeof(a))
#define NSYNC std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);

using namespace std;

const int MAXN = 222222;

struct Node {
	int l, r;//区间[l,r]  
	int add;//区间的延时标记  
	//int sum;//区间和  
	//int mx; //区间最大值  
	int mn; //区间最小值  
}tree[MAXN << 2];//一定要开到4倍多的空间  

void pushup(int index) {
	//tree[index].sum = tree[index << 1].sum + tree[index << 1 | 1].sum;
	//tree[index].mx = max(tree[index << 1].mx, tree[index << 1 | 1].mx);
	tree[index].mn = min(tree[index << 1].mn, tree[index << 1 | 1].mn);
}
void pushdown(int index) {
	//说明该区间之前更新过  
	//要想更新该区间下面的子区间,就要把上次更新该区间的值向下更新  
	if (tree[index].add) {
		//替换原来的值  

		//tree[index<<1].sum = (tree[index<<1].r-tree[index<<1].l+1)*tree[index].add;
		//tree[index<<1|1].sum = (tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].add;
		//tree[index<<1].mx = tree[index].add;
		//tree[index<<1|1].mx = tree[index].add;
		tree[index << 1].mn = tree[index].add;
		tree[index << 1 | 1].mn = tree[index].add;
		tree[index << 1].add = tree[index].add;
		tree[index << 1 | 1].add = tree[index].add;
		tree[index].add = 0;
		//在原来的值的基础上加上val  

		/*tree[index << 1].sum += (tree[index << 1].r - tree[index << 1].l + 1)*tree[index].add;
		tree[index << 1 | 1].sum += (tree[index << 1 | 1].r - tree[index << 1 | 1].l + 1)*tree[index].add;
		tree[index << 1].mx += tree[index].add;
		tree[index << 1 | 1].mx += tree[index].add;
		tree[index << 1].mn += tree[index].add;
		tree[index << 1 | 1].mn += tree[index].add;
		tree[index << 1].add += tree[index].add;
		tree[index << 1 | 1].add += tree[index].add;
		tree[index].add = 0;*/
	}
}
void build(int l, int r, int index) {
	tree[index].l = l;
	tree[index].r = r;
	tree[index].add = 0;//刚开始一定要清0  
	if (l == r) {
		//scanf("%d", &tree[index].sum);
		tree[index].mn;// = tree[index].mx = tree[index].sum;
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, index << 1);
	build(mid + 1, r, index << 1 | 1);
	pushup(index);
}
void update(int l, int r, int index, int val) {
	if (l <= tree[index].l && r >= tree[index].r) {
		//tree[index].sum = (tree[index].r-tree[index].l+1)*val;
		tree[index].mn = val;
		//tree[index].mx = val;
		tree[index].add = val;//延时标记 
		//tree[index].sum += (tree[index].r - tree[index].l + 1)*val;
		//tree[index].mn += val;
		//tree[index].mx += val;
		//tree[index].add += val;//延时标记  
		return;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r) >> 1;
	if (l <= mid) {
		update(l, r, index << 1, val);
	}
	if (r > mid) {
		update(l, r, index << 1 | 1, val);
	}
	pushup(index);
}
int query(int l, int r, int index) {
	if (l <= tree[index].l && r >= tree[index].r) {
		//return tree[index].sum;  
		//return tree[index].mx;
		return tree[index].mn;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r) >> 1;
	//int ans = 0;
	//int Max = 0;
	int Min = INF;
	if (l <= mid) {
		//ans += query(l, r, index << 1);
		//Max = max(query(l, r, index << 1), Max);
		Min = min(query(l, r, index << 1), Min);
	}
	if (r > mid) {
		//ans += query(l, r, index << 1 | 1);
		//Max = max(query(l, r, index << 1 | 1), Max);
		Min = min(query(l, r, index << 1 | 1), Min);
	}
	//return ans;  
	//return Max;
	return Min;
}

struct node {
	int s, val;
} demo[222222];
bool cmp(const node &a,const node &b) {
	return a.s < b.s;
}
bool cmp1(const node &a, const node &b) {
	return a.val < b.val;
}
int lId[222222], rId[222222], id[222222 << 2];

void slove() {
	int n;
	scanf("%d", &n);
	int cnt = 0;
	for (int i = 1; i <= n*2; i+=2) {
		scanf("%d%d", &demo[i].s, &demo[i+1].s);
		demo[i].val = i;
		demo[i + 1].val = i + 1;
	}
	sort(demo + 1, demo + n * 2 + 1, cmp);

	int now = 1, temp = demo[1].s;
	demo[1].s = 1;
	for (int i = 2; i <= n * 2; i++) {
		if (demo[i].s - temp > 1) now += 2;
		else if (demo[i].s - temp == 1)now++;
		temp = demo[i].s;
		demo[i].s = now;
	}
	sort(demo + 1, demo + n * 2 + 1, cmp1);
	build(1, 211111, 1);
	for (int i = 1; i <= n * 2; i += 2) {
		update(demo[i].s, demo[i+1].s, 1, demo[i].val);
	}

	int ans = 0;
	for (int i = 1; i <= n * 2; i += 2) {
		//cout << demo[i].s << " " << demo[i + 1].s << " " << demo[i].val <<" "<< query(demo[i].s, demo[i + 1].s, 1) << endl;
		if (query(demo[i].s, demo[i + 1].s, 1) == demo[i].val)
			ans++;
	}
	printf("%d\n", ans);
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		slove();
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值