The meaning of problems:
n-(n-<= 10000) successively individual posters, posters affixed to each given range li, ri (1 <= li <= ri <= 10000000). How many find the last poster can see.
Ideas:
tree line interval update problems, you can update lazy thinking optimized for the segment tree is 10 million Obviously too, the array can not, but only n 10000, can be discrete about.
But there is a discrete problem (pit) of this title, it is because we are next to tightly compressed, so there may be a problem of coverage errors
For example, data
3
1 10
1 3
7 10
after compression we should becomes
4 1
1 2
3 4
can so we visual look, you can see only two sections, the first to be covered. the real answer should be 3 fishes
this is what we should be stored in discrete array in c when considering each of the right boundary r + 1 is also stored so that it can effectively avoid the problem of error coverage.
Problem code:
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 5;
int st[maxn * 4], vis[maxn * 2], cnt[maxn * 2], a[maxn * 2];
int ans;
void pushdown(int o){ //懒人更新
if(st[o]) st[o << 1] = st[o << 1 | 1] = st[o], st[o] = 0;
}
void updata(int o, int l, int r, int L, int R,int res){
if(l >= L && r <= R){
st[o] = res;
return;
}
int m = (l + r) >> 1;
pushdown(o);
if(L <= m) updata(o << 1, l, m, L, R, res);
if(R > m) updata(o << 1 | 1, m + 1, r, L, R, res);
}
void query(int o, int l, int r){
if(st[o]) {
if(!vis[st[o]] && st[o] != 0){
vis[st[o]] = 1;
ans++;
}
return;
}
if(l == r) return ;
int m = (l + r) >> 1;
pushdown(o);
query(o << 1, l, m);
query(o << 1 | 1, m + 1, r);
}
int main(){
int c, n;
scanf("%d", &c);
while(c--){
scanf("%d", &n);
int cot = 0;
for(int i = 0; i < n; i++){
scanf("%d%d", &cnt[i * 2], &cnt[i * 2 + 1]);
a[cot++] = cnt[i * 2];
a[cot++] = cnt[i * 2 + 1];
a[cot++] = cnt[i * 2 + 1] + 1;
}
sort(a, a + cot);
int tot = (int)(unique(a, a + cot) - a); //unique函数返回值为第一个重复元素的指针
for(int i = 0; i < 2 * n; i++)
cnt[i] = (int)(lower_bound(a, a + cot, cnt[i]) - a + 1);
ans = 0; //初始化
fill(vis, vis + 2 * tot + 1, 0);
fill(st, st + 4 * tot + 1, 0);
for(int i = 0; i < n; i++){
updata(1, 1, tot, cnt[i * 2], cnt[i * 2 + 1], i + 1);
}
query(1, 1, tot);
printf("%d\n", ans);
}
}
Correct code:
#include<iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lc p<<1,s,mid
#define rc p<<1|1,mid+1,e
#define mid ((s+e)>>1)
#define CLR(A) memset(A,0,sizeof(A))
using namespace std;
const int N = 20005;
int col[N * 4], vis[N];
int le[N], ri[N], c[N * 2], ans;
void pushdown(int p)
{
if(col[p] == -1) return;
col[p << 1] = col[p << 1 | 1] = col[p];
col[p] = -1;
}
void update(int p, int s, int e, int l, int r, int v)
{
if(s >= l && e <= r)
{
col[p] = v;
return;
}
pushdown(p);
if(l <= mid) update(lc, l, r, v);
if(r > mid) update(rc, l, r, v);
}
void query(int p, int s, int e)
{
if(col[p] != -1)
{
if(!vis[col[p]])
vis[col[p]] = 1, ++ans;
return;
}
query(lc);
query(rc);
}
int compress(int n) //离散化
{
int k = 0;
for(int i = 0; i < n; ++i)
{
c[k++] = le[i];
c[k++] = ri[i];
c[k++] = ri[i] + 1;
}
sort(c, c + k);
return unique(c, c + k) - c - 1;
}
int main()
{
int cas, m, n, l, r;
scanf("%d", &cas);
while(cas--)
{
scanf("%d", &m);
for(int i = 0; i < m; ++i)
scanf("%d%d", &le[i], &ri[i]);
n = compress(m);
cout << "n = " << n << endl;
ans = 0;
CLR(col), CLR(vis);
for(int i = 0; i < m; ++i)
{
l = lower_bound(c, c + n, le[i]) - c + 1;
r = lower_bound(c, c + n, ri[i]) - c + 1;
update(1, 1, n, l, r, i + 1);
}
vis[0] = 1;
query(1, 1, n);
printf("%d\n", ans);
}
return 0;
}