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

来源:互联网 发布:为知笔记登录 编辑:程序博客网 时间:2024/04/28 15:14

题意:有一个很长的板子(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 HOMEint 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;}


0 0
原创粉丝点击