D - Mayor's posters

D - Mayor‘s posters

POJ - 2528

思路:线段树+离散化。

离散化时注意特殊情况,如果两个数相差大于一,离散时也应该差1。比如 1 3 离散后应该为 1 2。

错因:

1.二分时出现错误,,zz  zz  Orz

2. if(tree[now].l==tree[now].r)  return ; 这句话漏了。   Orz          还要注意这句话的位置。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 10000010
#define MAXN 10010
using namespace std;
int t,n,m,tot,ans;
int x[MAXN],y[MAXN];
int pos[M],hash[MAXN*4];
struct nond{
    int l,r,flag;
}tree[MAXN*16];
void build(int now,int l,int r){
    tree[now].l=l;tree[now].r=r;
    if(tree[now].l==tree[now].r){
        tree[now].flag=0;return ;
    }
    int mid=(tree[now].l+tree[now].r)/2;
    build(now*2,l,mid);
    build(now*2+1,mid+1,r);
}
void down(int now){
    tree[now*2].flag=tree[now].flag;
    tree[now*2+1].flag=tree[now].flag;
    tree[now].flag=0;
}
void change(int now,int l,int r,int x){
    if(tree[now].l==l&&tree[now].r==r){
        tree[now].flag=x;
        return ;
    }
    if(tree[now].flag)    down(now);
    int mid=(tree[now].l+tree[now].r)/2;
    if(r<=mid)    change(now*2,l,r,x);
    else if(l>mid)    change(now*2+1,l,r,x);
    else{ change(now*2,l,mid,x);change(now*2+1,mid+1,r,x); }
}
void query(int now){
    if(tree[now].flag){
        if(!pos[tree[now].flag])    ans++;
        pos[tree[now].flag]=1;return ;
    }
    if(tree[now].l==tree[now].r)    return ;
    int mid=(tree[now].l+tree[now].r)/2;
    query(now*2);query(now*2+1);
}
int findhash(int now){
    int l=1,r=tot;
    while(l<=r){
        int mid=(l+r)/2;
        if(hash[mid]<now)    l=mid+1;
        else    r=mid-1;
    }
    return l;
}
int main(){
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);ans=0;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&x[i],&y[i]);
            pos[++m]=x[i];pos[++m]=y[i];
        }
        sort(pos+1,pos+1+m);
        m=unique(pos+1,pos+1+m)-(pos+1);
        hash[++tot]=pos[1];
        for(int i=2;i<=m;i++){
            if(pos[i]-pos[i-1]>1)    hash[++tot]=pos[i-1]+1;
            hash[++tot]=pos[i];
        }
        memset(pos,0,sizeof(pos));
        build(1,1,tot);
        for(int i=1;i<=n;i++){
            int l=findhash(x[i]);
            int r=findhash(y[i]);
            change(1,l,r,i);
        }
        query(1);printf("%d\n",ans);
        m=0;tot=0;memset(pos,0,sizeof(pos));
    }
}

D - Mayor's posters

原文地址:https://www.cnblogs.com/cangT-Tlan/p/8467616.html

时间: 2024-11-09 23:40:26

D - Mayor's posters的相关文章

【线段树】Mayor&#39;s posters

[poj2528]Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 66154   Accepted: 19104 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their elect

POJ - 2528 - Mayor&#39;s posters 【线段树+离散化+补点】

http://poj.org/problem?id=2528 #include <cstdio> #include <iostream> #include <set> #include <cstring> #include <string> #define left rt<<1 #define right rt<<1|1 using namespace std; const int MAXN = 32768 + 5; in

POJ 2528 Mayor&#39;s posters (线段树区间更新+离散化)

题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值.由于l和r范围比较大,内存就不够了,所以就用离散化的技巧 比如将1 4化为1 2,范围缩小,但是不影响答案. 写了这题之后对区间更新的理解有点加深了,重点在覆盖的理解(更新左右两个孩子节点,然后值清空),还是要多做做题目. 1 #include <iostream> 2 #include <

POJ 2528 Mayor&#39;s posters (hash+线段树成段更新)

题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度.现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW.后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖先贴的海报.现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?(PS:看见一部分也算看到.) 思路:简单的成段更新,但是数据量是1千万,会MT,所以要区间压缩(离散化),保证覆盖的关系不变,离散化的时候有个易错的细节,poj数据水了,这个易错点引用h

POJ2528——Mayor&#39;s posters

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 44910   Accepted: 13059 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

POJ 2528 Mayor&#39;s posters.

~~~~ 一直MLE,才发现要写离散化操作.其他就是线段树的成段更新(每次用不同标记去更新区间),最后统计下有多少种标记就OK了. 题目链接:http://poj.org/problem?id=2528 大牛写的很详细,请戳:http://blog.csdn.net/metalseed/article/details/8041334 ~~~~ #include<cstdio> #include<cstring> #include<algorithm> #define N

poj 2528 Mayor&#39;s posters【离散化+线段树】

题目:poj 2528 Mayor's posters 题意:给一个长度非常长的墙上贴长度为ai的海报,由于有的会覆盖掉,求最后能看见的海报个数. 分析:题目和POJ2777 一模一样,方法也一样,只不过这个要离散化,其次要数组开大一点.至少2倍. 离散化的时候用了C++的 pair 类,还是比较好用的. 代码: #include <iostream> #include <algorithm> #include <utility> #include <cstrin

Mayor&#39;s posters

Mayor's posters Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electora

Mayor&#39;s posters(离散化线段树)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 54067   Accepted: 15713 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

Poj 2528 Mayor&#39;s posters (线段树+离散化)

题目连接: http://poj.org/problem?id=2528 题目大意: 有10000000块瓷砖,n张海报需要贴在墙上,每张海报所占的宽度和瓷砖宽度一样,长度是瓷砖长度的整数倍,问按照所给海报顺序向瓷砖上贴海报,最后有几张海报是可见的? 解题思路: 因为瓷砖块数和海报张数多,首选线段树,如果按照常规的建树方式,把瓷砖当做数的节点,肯定会MTL......... 所以我们可以用海报的起点和终点当做树的节点,这样树的节点才有20000个,但是这样建树的话,求海报覆盖了那些节点会很复杂,