线段树区间更新,区间统计+离散化 POJ 2528 Mayor's posters

题意:有一个很长的板子(10000000长),在上面贴n(n<=10000)张海报,问最后从外面能看到几张不同的海报。

因为板子有10000000长,直接建树肯定会爆,所以需要离散化处理,对于每张海报,有两个端点值,最后能看到几张海报跟他们的端点值的相对大小有关,跟绝对大小无关,所以就把所有海报的端点离散化处理,总共2n个端点,排序去重,对应p(p<=2n)个点。然后建树,因为p不超过20000,所以这样就可以接受了。区间更新时,因为我们只关心最外面海报的颜色有多少种,所以向下传递节点信息的时候把上面节点的信息去掉,这样在查询的时候就能方便一些,用一个标记数组记录总共有多少种颜色就可以了。

代码:

#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include<climits>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;

#define PB push_back
#define MP make_pair

#define REP(i,x,n) for(int i=x;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define FORD(i,h,l) for(int i=(h);i>=(l);--i)
#define SZ(X) ((int)(X).size())
#define ALL(X) (X).begin(), (X).end()
#define RI(X) scanf("%d", &(X))
#define RII(X, Y) scanf("%d%d", &(X), &(Y))
#define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
#define DRI(X) int (X); scanf("%d", &X)
#define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
#define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
#define OI(X) printf("%d",X);
#define RS(X) scanf("%s", (X))
#define MS0(X) memset((X), 0, sizeof((X)))
#define MS1(X) memset((X), -1, sizeof((X)))
#define LEN(X) strlen(X)
#define F first
#define S second
#define Swap(a, b) (a ^= b, b ^= a, a ^= b)
#define Dpoint  strcut node{int x,y}
#define cmpd int cmp(const int &a,const int &b){return a>b;}

 /*#ifdef HOME
    freopen("in.txt","r",stdin);
    #endif*/
const int MOD = 1e9+7;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long LL;
typedef pair<int,int> PII;
//#define HOME

int Scan()
{
	int res = 0, ch, flag = 0;

	if((ch = getchar()) == '-')				//判断正负
		flag = 1;

	else if(ch >= '0' && ch <= '9')			//得到完整的数
		res = ch - '0';
	while((ch = getchar()) >= '0' && ch <= '9' )
		res = res * 10 + ch - '0';

	return flag ? -res : res;
}
/*----------------PLEASE-----DO-----NOT-----HACK-----ME--------------------*/
int data[100000+10];

int n;
int a[20010];
int b[20010];
int u[40000];

void  pushdown(int rt)
{
    if(data[rt]!=-1)
    {
        data[rt<<1]=data[(rt<<1)+1]=data[rt];
        data[rt]=-1;
    }
}
void build(int l,int r,int rt)
{
    if(l==r)
    {
        data[rt]=-1;
        return;
    }
   int m=(l+r)>>1;
   build(l,m,rt<<1);
   build(m+1,r,(rt<<1)+1);
}
void update(int l,int r,int rt,int a,int b,int c)
{
    if(a<=l&&r<=b)
    {
        data[rt]=c;
        return;
    }
    pushdown(rt);
    int m=(l+r)>>1;
    if(a<=m)
    update(l,m,rt<<1,a,b,c);
    if(b>m)
        update(m+1,r,(rt<<1)+1,a,b,c);
}
int vis[20010];
int sum;
void query(int l,int r,int rt)
{if(data[rt]!=-1)
{
    if(!vis[data[rt]])
    {
        vis[data[rt]]=1;
        sum++;
    }
    return;
}
int m=(l+r)>>1;
query(l,m,rt<<1);
query(m+1,r,(rt<<1)+1);

}

int main()
{
int c;
RI(c);
while(c--)
{RI(n);
REP(i,0,n)
{
    RII(a[i],b[i]);
}
REP(i,0,n)
{
    u[i]=a[i];
    u[i+n]=b[i];
}
sort(u,u+2*n);
int p=unique(u,u+2*n)-u;
REP(i,0,n)
{int t=lower_bound(u,u+p,a[i])-u;
a[i]=t+1;
t=lower_bound(u,u+p,b[i])-u;
b[i]=t+1;
}
build(1,p,1);
REP(i,0,n)
{
    update(1,p,1,a[i],b[i],i);
}
MS0(vis);
sum=0;
query(1,p,1);
printf("%d\n",sum);
}

        return 0;
}

线段树区间更新,区间统计+离散化 POJ 2528 Mayor's posters

时间: 2024-10-09 10:47:25

线段树区间更新,区间统计+离散化 POJ 2528 Mayor's posters的相关文章

线段树+离散化 POJ 2528 Mayor&#39;s posters

题目传送门 题意:在一面墙上贴海报,有先后顺序,问最后有多少张不同的海报(指的是没被覆盖或者只是部分覆盖的海报) 分析:这题数据范围很大,直接搞超时+超内存,需要离散化:离散化简单的来说就是只取我们需要的值来用,比如说区间[1000,2000],[1990,2012] 我们用不到[-∞,999][1001,1989][1991,1999][2001,2011][2013,+∞]这些值,所以我只需要1000,1990,2000,2012就够了,将其分别映射到0,1,2,3,在于复杂度就大大的降下来

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

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

POJ 2528 Mayor&#39;s posters 离散化和线段树题解

本题就是要往墙上贴海报,问最后有多少可见的海报. 其实本题的难点并不是线段树,而是离散化. 因为数据很大,直接按原始数据计算那么就会爆内存和时间的. 故此需要把数据离散化. 比如有海报1 6   7 9   20 100  5 1000的原始数据,直接计算需要1-1000的内存,离散化之后只需要8内存,因为只有4组数据8个数. 本题更进一步高级一点的离散化就是需要把不相邻的两个数据插入一个数值,表示有空白的地方,不是所有海报都覆盖到的. 比如上面的数据要离散为:1 2  5 6  7 8 9 1

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

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 59239   Accepted: 17157 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 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值.由于l和r范围比较大,内存就不够了,所以就用离散化的技巧 比如将1 4化为1 2,范围缩小,但是不影响答案. 写了这题之后对区间更新的理解有点加深了,重点在覆盖的理解(更新左右两个孩子节点,然后值清空),还是要多做做题目. 1 #include <iostream> 2 #include <

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

Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for

poj 2528 Mayor&#39;s posters(线段树 离散化 区间更新 贴海报)

     这个题目本来对大神来说可能是水题, 对我就不行了,昨晚非折腾到下半夜一点 搞定, 并且可以总结出 ,只有把问题想清楚,或着看人家解题报告自己把问题和代码思路 搞清楚,才能谈的上调bug,否则根本就不知道错在哪儿.说说这个题目的理解,他是如何转化为线段树问题的呢?我们知道线段树有一个区间更新的东西,每张海报的宽度不就是一个区间么?那么我们可以用一棵树中的部分结点 来表示整张海报的可视部分,也就是说每个结点只允许表示一张完整的或着不完整的海报(好几个结点才可以表示成完整的一张海报),那么如

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

https://cn.vjudge.net/problem/POJ-2528 题意 给定一些海报,可能相互重叠,告诉你每个海报的宽度(高度都一样的)和先后叠放顺序,问没有被完全盖住的有多少张? 分析 海报最多10000张,但是墙有10000000块瓷砖长,海报不会落在瓷砖中间. 如果直接建树,就算不TLE,也会MLE.即单位区间长度太多. 其实10000张海报,有20000个点,最多有19999个区间.对各个区间编号,就是离散化.然后建树. 可以直接进行区间修改,最后再统计. 这里采用比较巧妙的

POJ 2528 Mayor&#39;s posters 区间离散化线段树

点击打开链接 Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 45894   Accepted: 13290 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their elector