1 条题解
-
0
线段树处理区间覆盖问题,注意需要离散化。
#include<cstdio> #include<cstdlib> #include<cstring> struct node{int x,y,p;}; node a[20010],b[20010]; int n,mm; struct tree{int l,r,lc,rc,c;bool update;}; tree tr[40010]; int len=0; bool col[20010]; void qsort(int l,int r) { int i=l,j=r; node mid,t; mid=b[(l+r)>>1]; while (i<=j) { while (b[i].x<mid.x) i++; while (b[j].x>mid.x) j--; if (i<=j) { t=b[i];b[i]=b[j];b[j]=t; i++;j--; } } if (l<j) qsort(l,j); if (i<r) qsort(i,r); } int bt(int l,int r) { len++; int now=len; tr[now].l=l; tr[now].r=r; tr[now].c=0; tr[now].lc=-1; tr[now].rc=-1; tr[now].update=false; if (l+1!=r) { int mid; mid=(l+r)>>1; tr[now].lc=bt(l,mid); tr[now].rc=bt(mid,r); } return now; } void update(int x) { tr[x].update=false; if (tr[x].lc!=-1 && tr[x].rc!=-1) { tr[tr[x].lc].update=tr[tr[x].rc].update=true; tr[tr[x].lc].c=tr[tr[x].rc].c=tr[x].c; } } void insert(int x,int l,int r,int p) { if (tr[x].l==l && tr[x].r==r) { tr[x].c=p; tr[x].update=true; return; } if (tr[x].update) update(x); int mid; mid=(tr[x].l+tr[x].r)>>1; if (r<=mid) insert(tr[x].lc,l,r,p); else if (l>=mid) insert(tr[x].rc,l,r,p); else {insert(tr[x].lc,l,mid,p);insert(tr[x].rc,mid,r,p);}; } int main() { scanf("%d",&n);n=n<<1; for (int i=1;i<=n;i+=2) { scanf("%d %d",&a[i].x,&a[i+1].x); a[i+1].x++; a[i].p=i; a[i+1].p=i+1; } for (int i=1;i<=n;i++) b[i]=a[i]; qsort(1,n); b[1].y=1; for (int i=2;i<=n;i++) if (b[i].x==b[i-1].x) b[i].y=b[i-1].y; else b[i].y=b[i-1].y+1; for (int i=1;i<=n;i++) { a[b[i].p].y=b[i].y; } len=0; bt(1,b[n].y); for (int i=1;i<=n;i+=2) { insert(1,a[i].y,a[i+1].y,i); } memset(col,false,sizeof(col)); for (int i=1;i<=len;i++) { if (tr[i].update) update(i); if (tr[i].lc==-1) col[tr[i].c]=true; } int ans=0; for (int i=1;i<=n;i++) if (col[i]) ans++; printf("%d\n",ans); }
- 1
信息
- ID
- 20
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者