首页 > 代码库 > (寒假集训) 卡片(离散化)

(寒假集训) 卡片(离散化)

卡片

时间限制: 1 Sec  内存限制: 128 MB
提交: 22  解决: 13
[提交][状态][讨论版]

题目描述

每个卡片的开头和结尾都有标记,把每张卡片看成数轴上的一条线段,开头和结尾的标记A,B为数轴上的两个点。每张卡片的颜色都不同。将卡片按照标记贴到数轴上,请问贴完卡片以后的数轴上一共有多少种不同的颜色。

输入

第1行:一个整数N,表示卡片的数量。

第2行至第N+1行:第i+1行给出了第i张卡片的头尾两个标记Ai,Bi,贴卡片的顺序与输入文件中出现的先后顺序一致。

输出

一个整数,表示能在数轴上看到的不同的颜色的数目。

样例输入

4
0 5
3 8
5 6
4 7

样例输出

3
【分析】由于不知道数据范围 所以我使用线段树写的 直接粘的板子
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#define inf 100000000
#define met(a,b) memset(a,b,sizeof a)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
using namespace std;
const int N = 2e5+5;
const int M = 4e5+5;
int n,sum[N],m,re=0;
int Tree[N],lazy[N];
int num[N*2],ans[N];
map<int,int>mp;
struct man{
    int l,r;
}a[N*2];
void pushdown(int pos){
    if(Tree[pos]){
        Tree[pos<<1]=Tree[pos<<1|1]=Tree[pos];
        Tree[pos]=0;
    }return;
}
 
void update(int L,int R,int val,int l,int r,int pos) {
    if(l>=L&&r<=R) {
        Tree[pos]=val;
        return;
    }
    if(l+1==r)return;
    int mid=(l+r)>>1;
    pushdown(pos);
    if(L<=mid) update(L,R,val,l,mid,pos<<1);
    if(mid<R)update(L,R,val,mid,r,pos<<1|1);
}
void query(int L,int R,int l,int r,int pos) {
    if(Tree[pos]&&!ans[Tree[pos]]){
        ans[Tree[pos]]=1;
        re++;
        return;
    }
    if(l+1==r)return;
    int mid=(l+r)>>1;
    pushdown(pos);
    int ans=0;
    if(L<=mid) query(L,R,l,mid,pos<<1);
    if(R>mid) query(L,R,mid,r,pos<<1|1);
    return;
}
int main() {
    int ll,rr,cnt=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a[i].l,&a[i].r);
        num[cnt++]=a[i].l;
        num[cnt++]=a[i].r;
    }
    sort(num,num+cnt);
    int all=0;
    for(int i=0;i<cnt;i++)if(!mp[num[i]])mp[num[i]]=++all;
    for(int i=1;i<=n;i++)update(mp[a[i].l],mp[a[i].r],i,1,all,1);
    query(1,all,1,all,1);
    printf("%d\n",re);
    return 0;
}

 


(寒假集训) 卡片(离散化)