最大不相交集合的数量。
思路是dp[i][j]表示已经有i个不相交集合下一个不相交集合的最右边界。
离散化后,通过贪心解。
/* 4343 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 typedef struct node_t {
int l, r; friend bool operator< (const node_t& a, const node_t& b) {
if (a.l == b.l)
return a.r < b.r;
return a.l < b.l;
}
} node_t; const int maxn = 1e5+;
int n, q;
int dp[][maxn*];
int X[maxn*], nx;
node_t nd[maxn]; int getId(int x, bool flag) {
if (flag)
return lower_bound(X, X+nx, x) - X;
else
return upper_bound(X, X+nx, x) - X - ;
} int calc(int l, int r) {
if (l > r)
return ; if (l==nx || r==-)
return ; int ret = ;
per(i, , ) {
if (dp[i][l] <= r) {
ret += (<<i);
l = dp[i][l];
}
} return ret;
} void solve() {
nx = ;
rep(i, , n) {
X[nx++] = nd[i].l;
X[nx++] = nd[i].r;
}
sort(nd, nd+n);
sort(X, X+nx);
nx = unique(X, X+nx) - X;
rep(i, , n) {
nd[i].l = getId(nd[i].l, true);
nd[i].r = getId(nd[i].r, false);
} int mn = nx, l, r = n-;
per(i, , nx) {
while (r>= && nd[r].l>=i) {
mn = min(mn, nd[r].r);
--r;
}
dp[][i] = mn;
}
rep(i, , )
dp[i][nx] = nx;
rep(i, , ) {
rep(j, , nx) {
dp[i][j] = dp[i-][dp[i-][j]];
}
} int ans; while (q--) {
scanf("%d %d", &l, &r);
l = getId(l, true);
r = getId(r, false);
ans = calc(l, r);
printf("%d\n", ans);
}
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif while (scanf("%d %d", &n, &q)!=EOF) {
rep(i, , n)
scanf("%d %d", &nd[i].l, &nd[i].r);
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}
数据发生器。
from copy import deepcopy
from random import randint, shuffle
import shutil
import string def GenDataIn():
with open("data.in", "w") as fout:
t = 10
bound = 10**5
ld = list(string.digits)
# fout.write("%d\n" % (t))
for tt in xrange(t):
n = randint(40, 50)
q = randint(20, 30)
fout.write("%d %d\n" % (n, q))
for i in xrange(n+q):
l = randint(1, bound-1)
r = randint(l, bound)
fout.write("%d %d\n" % (l, r)) def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName) if __name__ == "__main__":
GenDataIn()
MovDataIn()