poj 2528 Mayor's posters 离散化+线段树

来源:互联网 发布:如何评价张作霖 知乎 编辑:程序博客网 时间:2024/06/05 15:14

题目大意:

       在某段区间上贴海报,后面贴的会将前面贴的覆盖,问最后能够看到几种海报。

       区间大小1-10000000,海报最多100000

解决方法:

      很直观的就可以看出可以用线段树解决

      由于区间太大,所以不能够直接使用线段树。

      由海报数可知,改变的区间会很少,我们可以进行离散化处理。

      比如就3个区间【1-100】【2-50】【3-4】这道题中我们完全可以把其离散化为【1-6】【2-5】【3-4】,最终结果还是相同,并且还降低了时间与空间复杂度。

      离散化后就是对线段树的应用了,这里就不多讲了,可以看我之前的博客。

我的代码:

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#define maxn 1000000using namespace std;int tree[maxn*3];int  vis[20020];bool maps[10010];struct Point {  int x,y;}LLL[20020];int cmp(Point a,Point b){  return a.x<b.x;}int y1,y2,p;int pushdown(int o,int L,int R){  if (L<R){    tree[o*2]=tree[o];    tree[o*2+1]=tree[o];  }  return 0;}int maintain(int o,int L,int R){  if (R>L){    if (tree[o*2]==tree[o*2+1]) tree[o]=tree[o*2];    else tree[o]=-1;  }  return 0;}int query(int o,int L,int R){  //cout<<o<<" "<<L<<" "<<R<<" "<<tree[o]<<" |"<<y1<<" "<<y2<<" "<<p<<endl;  if (y1<=L&&y2>=R){    tree[o]=p+1;  }  else {    int M=L+(R-L)/2;    if (tree[o]==0|tree[o]==-1){       if (y1<=M) query(o*2,L,M);       if (y2>M) query(o*2+1,M+1,R);    }    else {        pushdown(o,L,R);        if (y1<=M) query(o*2,L,M);        if (y2>M) query(o*2+1,M+1,R);    }    maintain(o,L,R);  }  return 0;}int _sum;int sum(int o,int L,int R){  //cout<<o<<" "<<L<<" "<<R<<" "<<" "<<tree[o]<<endl;//" |"<<y1<<" "<<y2<<" "<<p<<endl;  if (tree[o]>0&&maps[tree[o]]==false){    _sum++;    maps[tree[o]]=true;    return 0;  }  else {    if (tree[o]>0) return 0;  }  if (tree[o]==0) return 0;  if (L<R){    int M=L+(R-L)/2;    sum(o*2,L,M);    sum(o*2+1,M+1,R);  }  return 0;}int main (){  //freopen("test.in","r",stdin);  //freopen("test.out","w",stdout);  int T; scanf("%d",&T);  while (T--){    int n;scanf("%d",&n);    memset(tree,0,sizeof(tree));    memset(vis,0,sizeof(vis));    memset(maps,0,sizeof(maps));    memset(LLL,0,sizeof(LLL));    for (int i=0;i<n;i++){      scanf("%d%d",&LLL[i*2].x,&LLL[i*2+1].x);      LLL[i*2].y=i*2;      LLL[i*2+1].y=i*2+1;    }    sort(LLL,LLL+n*2,cmp);    int len=2;int pry=LLL[0].x;LLL[0].x=1;    for (int i=1;i<n*2;i++){        if (pry==LLL[i].x){            LLL[i].x=len-1;        }        else {            pry=LLL[i].x;            LLL[i].x=len++;        }    }    for (int i=0;i<n;i++){      vis[LLL[i*2].y]=LLL[i*2].x;      vis[LLL[i*2+1].y]=LLL[i*2+1].x;    }    //cout<<LLL[n*2-1].x<<endl;    for (p=0;p<n;p++){        y1=vis[p*2];        y2=vis[p*2+1];        //cout<<y1<<" "<<y2<<endl;        query(1,1,LLL[n*2-1].x);    }    _sum=0;    sum(1,1,LLL[n*2-1].x);    printf("%d\n",_sum);  }  return 0;}


0 0