poj 2528 Mayor's posters

来源:互联网 发布:java程序员就业前景 编辑:程序博客网 时间:2024/06/03 23:48

   看到这道题就想起了牛插队的问题,如果没做过的同学可以去看看(poj 2182 Lost Cows)  ,肯定逆着来是肯定的, 不然无法进行判断。 还有一个问题便是这题的坐标范围实在太大了,如果真按照他的坐标来建立线段树,超时爆内存是肯定的事。  这题的点是突破口,  点的数目才10000,这时离散化便起作用了(我离散化也不大行,参考了下依然的),离散化了就变成了前面的奶牛问题了,这题很适合练习离散化的同学敲敲。

#include<cstdio>#include<iostream>#include<algorithm>#define L(u) (u<<1)#define R(u) (u<<1|1)using namespace std;const int Maxn = 10010;struct Pos{int num, i;}pos[Maxn*2];struct Node {int l,r;bool vis;}node[Maxn<<3];bool flag;void pushUp(int u){    if(node[L(u)].vis && node[R(u)].vis)     node[u].vis = true;}void build(int u,int left,int right){    node[u].l = left,node[u].r = right;    node[u].vis = false;//建树时都未访问过    if(node[u].l==node[u].r)    {        return;    }    int mid = (node[u].l+node[u].r)>>1;    build(L(u),left,mid);    build(R(u),mid+1,right);}void query(int u,int left,int right){    if(node[u].vis == true)//只要这块地方全部被覆盖了 就无需访问了    {        return;    }    if(node[u].l == left && node[u].r == right)    {        flag = true;//访问到某个没有被覆盖的点        node[u].vis = true;        return;    }    int mid = (node[u].l+node[u].r)>>1;    if(right<=mid)    return query(L(u),left,right);    else if(left>mid)    {        query(R(u),left,right);    }    else    {         query(L(u),left,mid);         query(R(u),mid+1,right);    }    pushUp(u);}bool cmp1(Pos a,Pos b){    return a.num < b.num;}bool cmp2(Pos a,Pos b)// 从后面向前面贴海报{    if(a.i == b.i)     return a.num < b.num;    return a.i>b.i;}int main(void){    int ncase, n;    scanf("%d",&ncase);    while(ncase--)    {        scanf("%d",&n);        for(int i = 1; i <= n; ++i)        {            scanf("%d%d",&pos[i*2-1].num,&pos[i*2].num);            pos[i*2-1].i = pos[i*2].i = i;        }        sort(pos+1, pos+1+2*n, cmp1);        int per = -1, k = 0;        for(int i = 1; i <= 2*n; ++i)        {            if(pos[i].num == per)            {                pos[i].num = k;            }            else            {                per = pos[i].num;                pos[i].num = ++k;            }        }         sort(pos+1, pos+1+2*n, cmp2);        build(1,1,k);        int sum = 0;//用来记录看不到的海报数目;        for(int i=1; i <= n; ++i)        {            flag = false;//用来判断是否这张海报是否能露出来            query(1,pos[i*2-1].num,pos[i*2].num);            if(flag)                sum++;        }        cout<<sum<<endl;    }    return 0;}


0 0
原创粉丝点击