POJ 2528 Mayor's posters 线段树+离散化
离散化 的大概思路 : 比如说给你一组 数据 1 4 1000 100000, 如果直接
开线段, 显然是浪费, 那么我们只要 进行 映射 :
1 1
4 2
1000 3
100000 4
接下来 我们只要对 1 2 3 4 建立线段树就行了 只需要
[1,4]的区间
离散化就相当于是先做映射,然后再建树。
本题大意:给定一些海报,可能相互重叠,告诉你每个海报的宽度(高度都一样的)和先后叠放顺序,问没有被完全盖住的有多少张?
海报最多10000张,但是墙有10000000块瓷砖长,海报不会落在瓷砖中间。
如果直接建树,就算不TLE,也会MLE。即单位区间长度太多。
其实10000张海报,有20000个点,最多有19999个区间。对各个区间编号,就是离散化。然后建数。
其实浮点数也是一样离散化的。
刚开始离散化利用map,果断tle了
改了就过了
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define ll long long #define ull unsigned long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int maxn=20000+20; struct Seg { int l,r; }; Seg seg[maxn>>1]; struct Gao { int v,dir,id,num; }; Gao gao[maxn]; bool vis[maxn>>1]; int val[maxn<<2]; int lazy[maxn<<2]; int ans; int solve(int ,int ); int main() { int test; scanf("%d",&test); while(test--){ int n; scanf("%d",&n); int len=0; for(int i=1;i<=n;i++){ int u,v; scanf("%d %d",&u,&v); seg[i].l=u,seg[i].r=v; gao[++len].v=u,gao[len].dir=0,gao[len].id=i; gao[++len].v=v,gao[len].dir=1,gao[len].id=i; } printf("%d\n",solve(n,len)); } return 0; } bool cmp(Gao x,Gao y) { return x.v<y.v; } void pushup(int rt) { if(val[rt<<1]==val[rt<<1|1]) val[rt]=val[rt<<1]; else val[rt]=-1; } void pushdown(int rt) { if(lazy[rt]){ lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt]; val[rt<<1]=val[rt<<1|1]=lazy[rt]; lazy[rt]=0; } } void update(int L,int R,int add,int l,int r,int rt) { if(L<=l&&R>=r){ lazy[rt]=add; val[rt]=add; return ; } pushdown(rt); int m=(l+r)>>1; if(L<=m) update(L,R,add,lson); if(R>m) update(L,R,add,rson); pushup(rt); } void query(int l,int r,int rt) { if(!val[rt]) return ; if(val[rt]>0){ if(!vis[val[rt]]){ ans++; vis[val[rt]]=true; } return ; } pushdown(rt); int m=(l+r)>>1; query(lson); query(rson); } int solve(int n,int len) { sort(gao+1,gao+len+1,cmp); int tot=0; gao[1].num=++tot; for(int i=2;i<=len;i++){ if(gao[i].v==gao[i-1].v) gao[i].num=tot; else gao[i].num=++tot; } for(int i=1;i<=len;i++){ if(!gao[i].dir){ seg[gao[i].id].l=gao[i].num; } else{ seg[gao[i].id].r=gao[i].num; } } memset(val,0,sizeof val); memset(lazy,0,sizeof lazy); for(int i=1;i<=n;i++){ update(seg[i].l,seg[i].r,i,1,tot,1); } memset(vis,false,sizeof vis); ans=0; query(1,tot,1); return ans; }