BZOJ5029: 贴小广告 & BZOJ5168: [HAOI2014]贴海报
【传送门:BZOJ5029&BZOJ5168】
简要题意:
给出m段区间l[i],r[i],表示l[i]到r[i]的数全部变成i,求出最后有多少种不同的数
题解:
线段树+离散化
这是一道经典例题
先离散化l和r,注意如果离散的时候,两个值相差大于1,就要新加一个值
然后线段树维护区间颜色就行了
参考代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; struct trnode { int l,r,lc,rc,c; }tr[21000];int len; void bt(int l,int r) { len++;int now=len; tr[now].l=l;tr[now].r=r;tr[now].c=-1; tr[now].lc=tr[now].rc=-1; if(l<r) { int mid=(l+r)/2; tr[now].lc=len+1;bt(l,mid); tr[now].rc=len+1,bt(mid+1,r); } } bool v[1100]; void wen(int now,int l,int r) { if(tr[now].c!=-1) { v[tr[now].c]=true; return ; } int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; if(r<=mid) wen(lc,l,r); else if(l>mid) wen(rc,l,r); else wen(lc,l,mid),wen(rc,mid+1,r); } void change(int now,int l,int r,int k) { if(l==tr[now].l&&r==tr[now].r) { tr[now].c=k; return ; } int lc=tr[now].lc,rc=tr[now].rc,mid=(tr[now].l+tr[now].r)/2; if(tr[now].c>0) { tr[lc].c=tr[now].c; tr[rc].c=tr[now].c; } if(r<=mid) change(lc,l,r,k); else if(mid<l) change(rc,l,r,k); else { change(lc,l,mid,k); change(rc,mid+1,r,k); } if(tr[lc].c==tr[rc].c&&tr[lc].c!=-1) tr[now].c=tr[lc].c; else tr[now].c=-1; } struct ask { int l,r,c; bool bk; ask() { bk=false; } }A[1100]; struct LSnode { int y,p,op; }w[2100];int tot; bool cmp(LSnode n1,LSnode n2){return n1.y<n2.y;} int main() { int n,m; scanf("%d%d",&n,&m); tot=0; for(int i=1;i<=m;i++) { scanf("%d%d",&A[i].l,&A[i].r);A[i].c=i; if(A[i].l>n) A[i].bk=true; if(A[i].r>n) A[i].r=n; tot++;w[tot].y=A[i].l,w[tot].p=i;w[tot].op=1; tot++;w[tot].y=A[i].r,w[tot].p=i;w[tot].op=2; } sort(w+1,w+1+tot,cmp); int tt=0,mmax=0; for(int i=1;i<=tot;i++) { if(w[i].y!=w[i-1].y) tt++; if(w[i].y!=w[i-1].y+1&&w[i].y!=w[i-1].y) tt++; if(w[i].op==1) A[w[i].p].l=tt; else A[w[i].p].r=tt; } len=0;bt(1,tt);tr[1].c=-1; for(int i=1;i<=m;i++) if(A[i].bk==false) change(1,A[i].l,A[i].r,A[i].c); memset(v,false,sizeof(v)); wen(1,1,tt); int ans=0; for(int i=1;i<=m;i++) if(v[i]==true) ans++; printf("%d\n",ans); return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚