poj 2528 Mayor's posters (线段树+离散化)
生活随笔
收集整理的這篇文章主要介紹了
poj 2528 Mayor's posters (线段树+离散化)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
/*離散化+線段樹由于 數據的輸入最大是 10000000 ,直接用開數組肯點會超,所以要將起離散話,首先 ,我們存儲輸入的邊,將其離散化,后面的就和一般的線段樹一樣可。
*/#include<stdio.h>
#include<stdlib.h>
#define N 10040
struct node
{int l;int r;
}p[N*2];
struct color
{int l;int r;int c;
}q[N*8];
int cmp ( const void *a , const void *b )
{
return *(int *)a - *(int *)b;
}
int addre[N*4],sum,m,pos[N*4],vis[N];
void build(int x,int l,int r)
{q[x].l=l;q[x].r=r;q[x].c=0;if(l==r)return ;int mid=(l+r)/2;build(x*2,l,mid);build(x*2+1,mid+1,r);
}
int find(int x)//離散化后的查詢
{int head=1,tail=m-1;while(head<=tail){int mid=(head+tail)/2;if(addre[mid]==x)return mid;if(addre[mid]<x)head=mid+1;elseif(addre[mid]>x)tail=mid-1;}return 0;
}
void change(int x,int l,int r,int color)
{if(q[x].l==l&&q[x].r==r){q[x].c=color;return ;}if(q[x].c!=-1)//下分到子節點{q[x*2].c=q[x].c;q[x*2+1].c=q[x].c;q[x].c=-1;}int mid=(q[x].l+q[x].r)/2;if(r<=mid)change(x*2,l,r,color);else{if(l>mid)change(x*2+1,l,r,color);else{change(x*2,l,mid,color);change(x*2+1,mid+1,r,color);}}}
void Get(int x,int l,int r)
{if(q[x].c==0)return ;if(q[x].c!=-1){if(!vis[q[x].c])//避免重復計算{vis[q[x].c]=1;sum++;}return ;}int mid=(q[x].l+q[x].r)/2;if(r<=mid)Get(x*2,l,r);else{if(l>mid)Get(x*2+1,l,r);else{Get(x*2,l,mid);Get(x*2+1,mid+1,r);}}
}
int main()
{int T,n,i;scanf("%d",&T);while(T--){scanf("%d",&n);int k=1;for(i=1;i<=n;i++){scanf("%d%d",&p[i].l,&p[i].r);pos[k++]=p[i].l;pos[k++]=p[i].r;}qsort(pos,k,sizeof(pos[0]),cmp);addre[1]=pos[1];m=2;for(i=1;i<=k;i++){if(pos[i]!=pos[i-1]){addre[m++]=pos[i];//離散化,用原來點的下標,來代替點,實現離散化}}build(1,1,m-1);for(i=1;i<=n;i++){int l=find(p[i].l);//離散化,用原來點的下標,來代替點,實現離散化int r=find(p[i].r);change(1,l,r,i);}sum=0;for(i=0;i<=n;i++)vis[i]=0;Get(1,1,m-1);printf("%d\n",sum);}
}
轉載于:https://www.cnblogs.com/acSzz/archive/2012/04/13/2446301.html
總結
以上是生活随笔為你收集整理的poj 2528 Mayor's posters (线段树+离散化)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: setTimeout and jquer
- 下一篇: 各种好用的代码生成器