题目大意:往一面墙上贴与墙等高的海报,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 }