您的位置:首页 > 其它

POJ_2528_Mayor's posters

2016-04-10 11:19 330 查看
//这题的数据比较水,可以参见http://blog.csdn.net/metalseed/article/details/8039326里关于这题的解释,然后可以发现网上的AC代码都是由于数据简单的
//原因水过去的.然后我的做法并没用延时标记,用的是子区间向父区间推导,找到最大的color.
#include<iostream>
#include<cstdio>
#include<sstream>
#include<string>
#include<vector>
#include<list>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#include<cmath>
#pragma warning(disable:4996)
using std::cin;
using std::cout;
using std::endl;
using std::stringstream;
using std::string;
using std::vector;
using std::list;
using std::pair;
using std::set;
using std::multiset;
using std::map;
using std::multimap;
using std::stack;
using std::queue;
template<typename ElemType>
class Interval
{
public:
ElemType first, second, color, increment;
Interval()
{
first = second = color = increment = 0;
}
Interval(const ElemType &f, const ElemType &s)
{
first = f;
second = s;
color = increment = 0;
}
Interval(const pair<ElemType, ElemType>&p)
{
first = p.first;
second = p.second;
color = 0;
}
ElemType mid()
{
return first + (length() - 1) / 2;
}
ElemType length()
{
return second - first + 1;
}
};
template<typename ElemType>
class SegTree
{
public:
vector<Interval<ElemType> >tree;
SegTree() {}
SegTree(const ElemType &n)
{
tree.resize(4 * n);
}
int size()
{
return tree.size();
}
void resize(const ElemType &n)
{
tree.resize(n);
}
//以数组形式建立线段树,当数据离散化之后,调用build(min,max,1)
void build(Interval<ElemType>interval, ElemType parent,ElemType &leaf,ElemType &size)
{
tree[parent] = interval;
if (interval.first == interval.second)
{
leaf = std::min(leaf, parent);
size = std::max(size, parent);
return;//当为元线段时停止递归
}
ElemType mid = (interval.first + interval.second) / 2;
build({ interval.first,mid }, 2 * parent,leaf, size);
build({ mid + 1,interval.second }, 2 * parent + 1,leaf, size);
}
//给闭区间都染上color
void insert(Interval<ElemType>interval, ElemType parent, const ElemType &color)
{
if (tree[parent].first == interval.first&&interval.second == tree[parent].second)
{
tree[parent].color = color;
return;
}
ElemType mid = tree[parent].mid();
if (interval.second <= mid)
{
insert(interval, parent * 2, color);
}
else if (interval.first > mid)
{
insert(interval, parent * 2 + 1, color);
}
else
{
insert({ interval.first,mid }, parent * 2, color);
insert({ mid + 1,interval.second }, parent * 2 + 1, color);
}
}
int getColor(int child)
{
if (child == 1)
{
return tree[child].color;
}
return  std::max(tree[child].color, getColor(child / 2));
}
};
vector<pair<int, int> >discretize(int &size)
{
int amount;
scanf("%d", &amount);
map<int, int>Map;
vector<pair<int, int> >interval;
while (amount--)
{
int left, right;
scanf("%d%d", &left,&right);
interval.push_back({ left,right });
Map.insert({ left,0 });
Map.insert({ right,0 });
}
int i = 0;
for (map<int, int>::iterator iter = Map.begin(); iter != Map.end(); iter++)
{
iter->second = ++i;
}
size = i;
for (size_t i = 0; i < interval.size(); i++)
{
interval[i].first = Map[interval[i].first];
interval[i].second = Map[interval[i].second];
}
return interval;
}
int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt","w",stdout);
int T; cin >> T;
while (T--)
{
int size = 0,leaf=2000000000;
vector<pair<int, int> >interval = discretize(size);
SegTree<int> segtree(size + 1);
segtree.build({ 1,size }, 1,leaf, size);
segtree.resize(size + 1);
for (size_t i = 0; i < interval.size(); i++)
{
segtree.insert(interval[i], 1, i + 1);
}
set<int>Set;
for (int i = leaf; i < segtree.size(); i++)
{
if (segtree.tree[i].first&&segtree.tree[i].first == segtree.tree[i].second)
{
Set.insert(segtree.getColor(i));
}
}
cout << Set.size() << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: