POJ 2528 Mayor's posters(离散+线段树)

题目大意:往一面墙上贴与墙等高的海报,n次贴完后,求可以看见的海报总数(看见一部分也算)

思路:明显的区间维护,用线段树,不过裸的线段树超时超空间,可以把坐标离散,得到不超过200000个有效点,每个点都表示一个小区间(a[i]~a[i+1]这一段),然后就可以轻松地解决了。不过题目有个坑,给定的右坐标其实不是实际坐标,还要+1,区间总数等于有效点数 -1,更新的时候把查找到的右端点-1再代入,具体见代码:

  1 /**********************************************
  2 ***    Problem:
  3 ***    Author:        JKL
  4 ***    University:    CSUST
  5 ***    Team:          __Dream
  6 ***    Email:          [email protected]
  7 ***    My Blog:        http://www.cnblogs.com/jklongint/
  8 ***********************************************/
  9 //===================================================
 10 #include <iostream>
 11 #include <fstream>
 12 #include <sstream>
 13 #include <iomanip>
 14 #include <cstdio>
 15 #include <cstdlib>
 16 #include <cmath>
 17 #include <cassert>
 18 #include <numeric>
 19 #include <ctime>
 20 #include <algorithm>
 21 #include <cstring>
 22 #include <string>
 23 #include <vector>
 24 #include <queue>
 25 #include <map>
 26 #include <stack>
 27 #include <list>
 28 #include <set>
 29 #include <bitset>
 30 #include <deque>
 31 using namespace std;
 32 //---------------------------------------------------
 33 #define mem(a,b) memset(a,b,sizeof(a))
 34 #define GO cout<<"HelloWorld!"<<endl
 35 #define Case(x) cout<<"Case "<<x<<":"
 36 #define foru(i,n) for(int i=1; i <= n; i++)
 37 #define ford(i,n) for(int i = n; i >= 1; i--)
 38  #define fin freopen("input.txt","r",stdin);
 39  #define fout freopen("output.txt","w",stdout)
 40 #define lson  l, m, rt << 1
 41 #define rson  m + 1, r, rt << 1 | 1
 42
 43 #define sqr(a)  ((a)*(a))
 44 #define abs(a) ((a>0)?(a):-(a))
 45 #define pii pair<int,int>
 46
 47 #define fmax(a,b) max(a,b)
 48 #define fmin(a,b) min(a,b)
 49 #define fmax3(a,b,c)  (fmax(a,fmax(a,b)))
 50 #define fmin3(a,b,c)  (fmin(a,fmin(a,b)))
 51
 52 #define sfi(x) scanf("%d",&x)
 53 #define sfL(x) scanf("%I64d",&x)
 54 #define sfc(x) scanf("%c",&x)
 55 #define sfd(x) scanf("%lf",&x)
 56 #define sfs(x) scanf("%s",x)
 57 #define sfii(a,b) scanf("%d%d",&a,&b)
 58 #define sfLL(a,b) scanf("%I64d%I64d",&a,&b)
 59 #define sfcc(a,b) scanf("%c%c",&a,&b)
 60 #define sfdd(a,b) scanf("%lf%lf",&a,&b)
 61 #define sfss(a,b) scanf("%s%s",a,b)
 62
 63 #define pfi(x) printf("%d",x)
 64 #define pfL(x) printf("%I64d",x)
 65 #define pfs(x) printf("%s",x)
 66 #define pfd(x) printf("%lf",x)
 67 #define pfc(x) print("%c",x)
 68 #define newLine pfs("\n")
 69 #define space pfs(" ")
 70
 71 //--------------------------------------------------------
 72 typedef long long LL;
 73 typedef unsigned long long ULL;
 74 typedef __int64 __LL;
 75 typedef unsigned __int64 __ULL;
 76
 77 typedef vector<int> vi;
 78 typedef vector<LL> vL;
 79 typedef vector<string> vs;
 80 typedef set<int> si;
 81 typedef map<int,int> mii;
 82 typedef map<LL,LL> mLL;
 83 typedef map<string,int> msi;
 84 typedef map<char,int> mci;
 85 //--------------------------------------------------------
 86 const int dx[4]={1,-1,0,0};
 87 const int dy[4]={0,0,1,-1};
 88  const int day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
 89  const int N6=1000006;
 90  const int N5=100006;
 91  const int N4=10006;
 92  const int N3=1006;
 93  const int N2=106;
 94  const int N=20009;
 95  const int MOD=1000000007;
 96  const LL LMAX=0x7fffffffffffffff;
 97  const LL IMAX=0x3fffffff;
 98  const double PI=3.14159265359;
 99 //--------------------------------------------------------
100 template< class T > T gcd(T a, T b) { return (b != 0 ? gcd<T>(b, a%b) : a); }
101 template< class T > T lcm(T a, T b) { return (a / gcd<T>(a, b) * b); }
102
103 //------------------------------------------------------------
104 struct TreeNode{
105     int  mark;
106 };
107 //=================================================================
108 TreeNode tree[N << 2];
109 int T, n, cnt, flag[N], x[N], y[N], a[N], b[N];
110 void PushUP(int rt)
111 {
112     int tl = tree[rt << 1].mark, tr = tree[rt << 1 | 1].mark;
113     if(tl != tr || tl == -1) tree[rt].mark = -1;
114     else tree[rt].mark = tl;
115 }
116 void PushDOWN(int rt)
117 {
118     int rl = rt << 1, rr = rt << 1 | 1;
119     if(tree[rt].mark > 0){
120         tree[rl].mark = tree[rt].mark;
121         tree[rr].mark = tree[rt].mark;
122     }
123 }
124 void build(int l, int r, int rt)
125 {
126     tree[rt].mark = 0;
127     if(l == r)return;
128     int m = (l + r) >> 1;
129     build(lson);
130     build(rson);
131 }
132 void update(int L, int R, int p, int l, int r, int rt)
133 {
134     if(L <= l && R >= r){
135         tree[rt].mark = p;
136         return;
137     }
138     int m = (l + r) >> 1;
139     PushDOWN(rt);
140     if(L <= m) update(L, R, p, lson);
141     if(R > m) update(L, R, p, rson);
142     PushUP(rt);
143 }
144 int query(int p, int l, int r, int rt)
145 {
146     if(l == r){
147         return tree[rt].mark;
148     }
149     int m = (l + r) >> 1;
150     PushDOWN(rt);
151     if(p <= m)return query(p, lson);
152     else return query(p, rson);
153 }
154 void discrete()
155 {
156     cnt = 0;
157     foru(i, n){
158         a[++cnt] = x[i];
159         a[++cnt] = y[i];
160     }
161     sort(a + 1, a + 1 + cnt);
162     int cc = 0;
163     foru(i, cnt){
164         if(a[i] != a[i - 1] || i == 1)b[++cc] = a[i];
165     }
166     cnt = cc;
167 }
168 int get(int x)
169 {
170     int l = 1, r = cnt;
171     while(l < r){
172         int m = (l + r) >> 1;
173         if(x < b[m]) r = m - 1;
174         if(x == b[m]) return m;
175         if(x > b[m]) l = m + 1;
176     }
177     return l;
178 }
179 int main()
180 {
181     //fin;//fout;//freopen("input.txt","r",stdin);
182    cin>>T;
183    while(T--){
184         cin>>n;
185         foru(i, n)sfii(x[i], y[i]),y[i]++;
186         discrete();
187         build(1, cnt - 1, 1);
188         foru(i, n){
189             int l = get(x[i]), r = get(y[i]) - 1;
190             if(r >= l)update(l, r, i, 1, cnt - 1, 1);
191         }
192         mem(flag, 0);
193         int ans = 0;
194         foru(i, cnt - 1){
195             int c = query(i, 1, cnt - 1, 1);
196             if(!flag[c] && c > 0){
197                 flag[c] = 1;
198                 ans++;
199             }
200         }
201         cout<<ans<<endl;
202    }
203     return 0;
204 }

POJ 2528 Mayor's posters(离散+线段树)

时间: 2024-08-03 23:29:45

POJ 2528 Mayor's posters(离散+线段树)的相关文章

(中等) 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 (线段树+区间离散)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 45031   Accepted: 13080 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 (hash+线段树成段更新)

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

POJ 2528——Mayor&#39;s posters——————【线段树区间替换、找存在的不同区间】

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

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(线段树+离散化)

这道题目让我又重新认识了一下离散化: 首先总结一下离散化的特点: 1)有时区间的端点并不是整数,或者区间太大导致建树内存开销过大而MLE,那么就需要进行离散化后再建树. 2)意思是将区间范围很大的数据集映射到较小的数据集,这样建树更加有效,或者说我们只取需要的值来用. 这个意思说到底就是进行映射,把原来很大的映射到一个较小的空间中去. 题意: 给定一些海报,它们可能相互重叠,告诉你每个海报的宽度(它们的高度都是一样的)和先后的叠放次序,问没有被完全盖住的海报有多少张? 这里我们注意到了数据的范围

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

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

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(离散化线段树)

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(线段树+离散化)

题目链接:Mayor's posters 题意:按顺序往墙上贴海报,可以重叠,问最后可以看到多少海报.(被覆盖的海报是看不到的) 注意: 因为数据比较大,所以不离散化,肯定爆内存. 还有就是,不能只是单纯的离散化,还要处理好点的边界 举个例子 4 2  10. 2  8 3  6 6  8 8  10 离散化后 2 3 6 8 10 1 2 3 4 5 覆盖掉了 1 5   和  1 4俩段 只剩下 2  3  .3  4. 4  5 答案是 3 但是正确答案是4 所以,离散化处理时要处理边界,