标签:
题意:给n张海报,按顺序贴海报,问最后能看到多少张不同的海报。
解法:成段更新线段树 + 离散化。这道题因为给出的数字是单位长度,所以普通的离散化是有问题的,借鉴了大神的方法:http://notonlysuccess.me/?p=978
一开始我的离散化方法是把单位长度改为数轴坐标……但是2 2 1 1 3 3这组样例是有问题的……TUT
代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<math.h>
#include<limits.h>
#include<time.h>
#include<stdlib.h>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define LL long long
using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
map <int, int> m;
int l[20005], r[20005];
int col[11111 << 4];
bool flag[20005];
int ans;
void pushDown(int rt)
{
if(col[rt] != -1)
col[rt << 1] = col[rt << 1 | 1] = col[rt];
col[rt] = -1;
}
void update(int ll, int rr, int c, int l, int r, int rt)
{
if(ll <= l && rr >= r)
{
col[rt] = c;
return ;
}
pushDown(rt);
int m = (l + r) >> 1;
if(ll <= m)
update(ll, rr, c, lson);
if(rr > m)
update(ll, rr, c, rson);
}
void query(int l, int r, int rt)
{
if(col[rt] != -1)
{
if(!flag[col[rt]])
{
ans++;
}
flag[col[rt]] = true;
return;
}
if(l == r)
return ;
int m = (l + r) >> 1;
query(lson);
query(rson);
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
m.clear();
memset(col, -1, sizeof col);
int n;
scanf("%d", &n);
int maxn = 1;
for(int i = 0; i < n; i++)
{
scanf("%d%d", &l[i], &r[i]);
m[l[i]]++;
m[r[i]]++;
}
map <int, int> :: iterator ite = m.begin(), ite1 = m.begin();
ite -> second = 0;
ite++;
for(; ite != m.end(); maxn++, ite++, ite1++)
{
if(ite -> first - ite1 -> first > 1)
m[ite -> first + 1] = maxn++;
ite -> second = maxn;
}
for(int i = 0; i < n; i++)
{
update(m[l[i]], m[r[i]], i, 0, maxn - 1, 1);
}
ans = 0;
memset(flag, 0, sizeof flag);
query(0, maxn - 1, 1);
printf("%d\n", ans);
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/Apro/p/4503059.html