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 }
View Code

 

你可能感兴趣的:(post)