题目链接 发现这道题可以用STL做,就犯了懒,学了学set的用法,不得不佩服c++的发明者啊 首先先感谢这位博主 set,顾名思义,就是数学上的集合——每个元素最多只出现一次,并且set中的元素已经从小到大排好序。 头文件:#include < set > 常用操作: begin() 返回set容器的第一个元素的地址 end() 返回set容器的最后一个元素地址 clear() 删除set容器中的所有的元素 empty() 判断set容器是否为空 max_size() 返回set容器可能包含的元素最大个数 size() 返回当前set容器中的元素个数 erase(it) 删除迭代器指针it处元素 insert(a) 插入某个元素
有了这个,便可以很容易的处理这道题目了,我们利用lower_bound寻找比当前插入元素的l大的r,即为不合法的元素,删去,依次处理就行了 细节:这个元素l&&r<查询出来的l,仍然是没有重叠的,即元素合法 需要注意的是end返回的是一个越界的地址,与lower_bound相似
#include <iostream> #include <cstdio> #include <set> using namespace std; struct node{//以r为第一关键字排序,显然 int lf,rt; bool operator<(const node&v)const{ if(rt==v.rt) return lf<v.lf; return rt<v.rt; } }; set<node> s;//定义set容器 int main() { int n; set<node>::iterator it; scanf("%d",&n); for(int i=1;i<=n;i++) { char a; cin>>a; if(a=='A') { int l,r; scanf("%d%d",&l,&r); int cnt=0; while(1) { it=s.lower_bound((node){0,l}); if(it!=s.end()&&r>=it->lf)//注意细节处理 { s.erase(it);//删去it地址的元素 cnt++; continue; } break; } s.insert((node){l,r});//插入新元素 printf("%d\n",cnt); } else printf("%d\n",s.size());//输出set容器中元素的个数 } return 0; }方法2:线段树 我们先将所有的操作读入进来,进行离线 cnt[i]表示加入i需要删除的前面的区间的个数 倒着进行处理,在线段树中维护最小值,先查询插入区间中的最小值 假设插入4时,它的区间中有5,6,那我们就将5的cnt++,因为4与5,6,同时矛盾时,5插入时4已删除,4对6已经没有影响,所以维护最小值
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int cnt[300001]; int st[300001*4]; int m[300001*4]; struct we{ char c; int l,r; }a[200100]; inline void push_down(int o) { m[(o<<1)]=min(m[o],m[(o<<1)]); st[(o<<1)]=min(st[(o<<1)],m[o<<1]); m[(o<<1)+1]=min(m[(o<<1)+1],m[o]); st[(o<<1)+1]=min(st[(o<<1)+1],m[(o<<1)+1]); } void query(int o,int l,int r,int ql,int qr,int sum) { if(ql<=l&&qr>=r) { m[o]=min(m[o],sum); st[o]=m[o]; return; } if(m[o]!=m[0]) push_down(o); int mid=(l+r)>>1; if(ql<=mid) query((o<<1),l,mid,ql,qr,sum); if(mid+1<=qr) query((o<<1)+1,mid+1,r,ql,qr,sum); st[o]=min(st[(o<<1)],st[(o<<1)|1]); } int ask(int o,int l,int r,int ql,int qr) { if(ql<=l&&qr>=r) return st[o]; if(m[o]!=m[0]) push_down(o); int mid=(l+r)>>1; int ans=m[0]; if(ql<=mid) ans=min(ans,ask((o<<1),l,mid,ql,qr)); if(mid+1<=qr) ans=min(ask((o<<1)+1,mid+1,r,ql,qr),ans); return ans; } int main() { memset(m,127,sizeof(m)); memset(st,127,sizeof(st)); int n; scanf("%d",&n); for(int i=1;i<=n;i++) { cin>>a[i].c; if(a[i].c=='A') cin>>a[i].l>>a[i].r; } for(int i=n;i>=1;i--) { if(a[i].c=='A') { int d=ask(1,1,100001,a[i].l,a[i].r); if(d!=m[0]) cnt[d]++; query(1,1,100001,a[i].l,a[i].r,i); } } int ans=0; for(int i=1;i<=n;i++) { if(a[i].c=='A') { ans=ans+1-cnt[i]; printf("%d\n",cnt[i]); } else printf("%d\n",ans); } return 0; }