+ Segment tree update interval discrete - Mayor's posters POJ - 2528

Mayor’s posters POJ - 2528

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;
}
Published 92 original articles · won praise 7 · views 3727

Guess you like

Origin blog.csdn.net/dajiangyou123456/article/details/104443727