您的位置:首页 > 产品设计 > UI/UE

【HDOJ】4343 Interval query

2016-02-13 00:04 489 查看
最大不相交集合的数量。
思路是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+5;
int n, q;
int dp[18][maxn*2];
int X[maxn*2], 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 - 1;
}

int calc(int l, int r) {
if (l > r)
return 0;

if (l==nx || r==-1)
return 0;

int ret = 0;
per(i, 0, 18) {
if (dp[i][l] <= r) {
ret += (1<<i);
l = dp[i][l];
}
}

return ret;
}

void solve() {
nx = 0;
rep(i, 0, 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, 0, n) {
nd[i].l = getId(nd[i].l, true);
nd[i].r = getId(nd[i].r, false);
}

int mn = nx, l, r = n-1;
per(i, 0, nx) {
while (r>=0 && nd[r].l>=i) {
mn = min(mn, nd[r].r);
--r;
}
dp[0][i] = mn;
}
rep(i, 0, 18)
dp[i][nx] = nx;
rep(i, 1, 18) {
rep(j, 0, nx) {
dp[i][j] = dp[i-1][dp[i-1][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, 0, n)
scanf("%d %d", &nd[i].l, &nd[i].r);
solve();
}

#ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif

return 0;
}


数据发生器。

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()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: