POJ-2528(线段树+离散化)

匿名 (未验证) 提交于 2019-12-02 23:57:01

Mayor's posters

POJ-2528

  • 本题是线段树的区间更新和离散化的结合。
  • 代码中需要注意的就是这里要加入一个去重的操作。而且我这里建树的时候是从1开始的,所以下标的问题要注意。
  • 还有一个需要注意的地方就是根据题目的意思在离散化之后,可能会出现一个问题,就是[1,10],[1, 4],[6,10]这种情况会发生错误。这里直接将4-6看成是连续的,但是实际上着中间还有一个5是属于第一个区间的。所以针对这种情况需要额外加一个点。
  • 还有一个数据量的问题也需要注意。数组尽量开大一点,要不然不是报RE就是WA(亲测)。
//离散化+线段树 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> using namespace std; const int maxn=100014; int n,m; int lazy[maxn<<2]; int num[maxn<<1]; int left1[maxn]; int right1[maxn]; bool vis[maxn]; int ans=0; void build(int id,int l,int r){     if(l==r)         return;     int lc=id<<1;     int rc=id<<1|1;     int mid=(l+r)>>1;     build(lc,l,mid);     build(rc,mid+1,r); } void pushdown(int id,int l,int r){     if(lazy[id]==0)//这里要注意,不然这些lazy数组都会被赋值为0         return;     int lc=id<<1;     int rc=id<<1|1;     lazy[lc]=lazy[id];     lazy[rc]=lazy[id];     lazy[id]=0; } void update(int id,int l,int r,int p,int q,int v){     if(p<=l&&q>=r){         lazy[id]=v;         return;     }     pushdown(id,l,r);     int mid=(l+r)>>1;     int lc=id<<1;     int rc=id<<1|1;     if(p<=mid) update(lc,l,mid,p,q,v);     if(q>mid) update(rc,mid+1,r,p,q,v); } void query(int id,int l,int r){     if(lazy[id]&&!vis[lazy[id]]){         ans++;         vis[lazy[id]]=1;         return;     }     if(l==r)         return;     pushdown(id,l,r);     int lc=id<<1;     int rc=id<<1|1;     int mid=(l+r)>>1;     query(lc,l,mid);     query(rc,mid+1,r); } int main(){     ios::sync_with_stdio(false);     cin.tie(0);     int t;     cin>>t;     while(t--){         ans=0;         memset(lazy,0,sizeof(lazy));         memset(vis,0,sizeof(vis));         cin>>n;         int cnt=1;         for(int i=1;i<=n;i++){             int a,b;             cin>>left1[i]>>right1[i];             num[cnt++]=left1[i];             num[cnt++]=right1[i];         }         sort(num+1,num+cnt);         m=unique(num+1,num+cnt)-(num+1);         //cout<<m<<endl;         //在所有相隔距离大于1的点之间都插入一个单点(让它充当那段被裸露区间)         int an=m;         for(int i=2;i<=m;i++){             if(num[i]-num[i-1]>1){                 num[++an]=num[i-1]+1;             }         }         sort(num+1,num+an+1);         build(1,1,an);         // for(int i=1;i<=an;i++)         //     cout<<num[i]<<endl;         for(int i=1;i<=n;i++){             int p=lower_bound(num+1,num+an+1,left1[i])-num;             int q=lower_bound(num+1,num+an+1,right1[i])-num;             //cout<<p<<" "<<q<<endl;             update(1,1,an,p,q,i);         }         query(1,1,an);         cout<<ans<<endl;     }     //system("pause");     return 0; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!