标签:
最大不相交集合的数量。
思路是dp[i][j]表示已经有i个不相交集合下一个不相交集合的最右边界。
离散化后,通过贪心解。
1 /* 4343 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 typedef struct node_t { 44 int l, r; 45 46 friend bool operator< (const node_t& a, const node_t& b) { 47 if (a.l == b.l) 48 return a.r < b.r; 49 return a.l < b.l; 50 } 51 } node_t; 52 53 const int maxn = 1e5+5; 54 int n, q; 55 int dp[18][maxn*2]; 56 int X[maxn*2], nx; 57 node_t nd[maxn]; 58 59 int getId(int x, bool flag) { 60 if (flag) 61 return lower_bound(X, X+nx, x) - X; 62 else 63 return upper_bound(X, X+nx, x) - X - 1; 64 } 65 66 int calc(int l, int r) { 67 if (l > r) 68 return 0; 69 70 if (l==nx || r==-1) 71 return 0; 72 73 int ret = 0; 74 per(i, 0, 18) { 75 if (dp[i][l] <= r) { 76 ret += (1<<i); 77 l = dp[i][l]; 78 } 79 } 80 81 return ret; 82 } 83 84 void solve() { 85 nx = 0; 86 rep(i, 0, n) { 87 X[nx++] = nd[i].l; 88 X[nx++] = nd[i].r; 89 } 90 sort(nd, nd+n); 91 sort(X, X+nx); 92 nx = unique(X, X+nx) - X; 93 rep(i, 0, n) { 94 nd[i].l = getId(nd[i].l, true); 95 nd[i].r = getId(nd[i].r, false); 96 } 97 98 int mn = nx, l, r = n-1; 99 per(i, 0, nx) { 100 while (r>=0 && nd[r].l>=i) { 101 mn = min(mn, nd[r].r); 102 --r; 103 } 104 dp[0][i] = mn; 105 } 106 rep(i, 0, 18) 107 dp[i][nx] = nx; 108 rep(i, 1, 18) { 109 rep(j, 0, nx) { 110 dp[i][j] = dp[i-1][dp[i-1][j]]; 111 } 112 } 113 114 int ans; 115 116 while (q--) { 117 scanf("%d %d", &l, &r); 118 l = getId(l, true); 119 r = getId(r, false); 120 ans = calc(l, r); 121 printf("%d\n", ans); 122 } 123 } 124 125 int main() { 126 ios::sync_with_stdio(false); 127 #ifndef ONLINE_JUDGE 128 freopen("data.in", "r", stdin); 129 freopen("data.out", "w", stdout); 130 #endif 131 132 while (scanf("%d %d", &n, &q)!=EOF) { 133 rep(i, 0, n) 134 scanf("%d %d", &nd[i].l, &nd[i].r); 135 solve(); 136 } 137 138 #ifndef ONLINE_JUDGE 139 printf("time = %d.\n", (int)clock()); 140 #endif 141 142 return 0; 143 }
数据发生器。
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 10 10 bound = 10**5 11 ld = list(string.digits) 12 # fout.write("%d\n" % (t)) 13 for tt in xrange(t): 14 n = randint(40, 50) 15 q = randint(20, 30) 16 fout.write("%d %d\n" % (n, q)) 17 for i in xrange(n+q): 18 l = randint(1, bound-1) 19 r = randint(l, bound) 20 fout.write("%d %d\n" % (l, r)) 21 22 23 24 def MovDataIn(): 25 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 26 shutil.copyfile("data.in", desFileName) 27 28 29 if __name__ == "__main__": 30 GenDataIn() 31 MovDataIn()
标签:
原文地址:http://www.cnblogs.com/bombe1013/p/5187365.html