卡片
时间限制: 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; }
时间: 2024-10-09 11:10:34