zoukankan      html  css  js  c++  java
  • BZOJ1178或洛谷3626 [APIO2009]会议中心

    BZOJ原题链接

    洛谷原题链接

    第一个问题是经典的最多不相交区间问题,用贪心即可解决。
    主要问题是第二个,求最小字典序的方案。
    我们可以尝试从(1 o n)扫一遍所有区间,按顺序对每一个不会使答案变差的区间都尝试着去填,这样就可以保证方案的字典序最小。
    考虑如果快速判断该区间是否能成为最优解,开头先按右端点从小到大排序,左端点从大到小排序,再去除有包含关系的区间,这样使得讨论更为简单。
    设待插入的区间为([r,l]),该区间左边的第一个已插入的区间的右端点为(L),右边的第一个已插入的区间的左端点为(R)(S[i][j])表示([i,j])间有多少已插入的区间。
    则该区间能插入必须满足(S[L + 1][R - 1] = S[L + 1][r - 1] + S[l + 1][R - 1] + 1)
    对于快速计算(S),我们可以采用倍增的思想,设(ne[x][i])表示第(x)个区间后选择(2^i)个区间的最后一个区间下标,可以使用倍增在(nlogn)内预处理出来。
    维护已插入区间可以使用(C++ STL set)

    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<set>
    using namespace std;
    const int N = 2e5 + 10;
    const int M = 18;
    struct dd{
    	int x, y;
    	bool operator < (const dd &b) const
    	{
    		if (!(y ^ b.y))
    			return x > b.x;
    		return y < b.y;
    	}
    };
    dd a[N], b[N];
    int X[N], Y[N], ne[N][M], m, gn;
    set<dd>S;
    inline int re()
    {
    	int x = 0;
    	char c = getchar();
    	bool p = 0;
    	for (; c < '0' || c > '9'; c = getchar())
    		p |= c == '-';
    	for (; c >= '0' && c <= '9'; c = getchar())
    		x = x * 10 + c - '0';
    	return p ? -x : x;
    }
    inline int lowbod(int x)
    {
    	int l = 1, r = m, mid, an = m + 1;
    	while (l <= r)
    	{
    		mid = (l + r) >> 1;
    		if (X[mid] >= x)
    		{
    			an = mid;
    			r = mid - 1;
    		}
    		else
    			l = mid + 1;
    	}
    	return an;
    }
    inline int calc(int l, int r)
    {
    	int x = lowbod(l);
    	if (x > m || Y[x] > r)
    		return 0;
    	int s = 1;
    	for (int i = gn; ~i; i--)
    		if (ne[x][i] && Y[ne[x][i]] <= r)
    		{
    			s += 1 << i;
    			x = ne[x][i];
    		}
    	return s;
    }
    int main()
    {
    	int i, j, n, l, r, L, R;
    	n = re();
    	for (i = 1; i <= n; i++)
    	{
    		a[i].x = re();
    		a[i].y = re();
    		b[i] = a[i];
    	}
    	sort(b + 1, b + n + 1);
    	for (i = 1; i <= n; i++)
    		if (b[i].x > b[m].x || !m)
    			b[++m] = b[i];
    	for (i = 1; i <= m; i++)
    	{
    		X[i] = b[i].x;
    		Y[i] = b[i].y;
    	}
    	for (i = j = 1; i <= m; i++)
    	{
    		for (; j <= m && b[j].x <= b[i].y; j++);
    		if (j <= m)
    			ne[i][0] = j;
    	}
    	gn = log2(m);
    	for (j = 1; j <= gn; j++)
    		for (i = 1; i <= m; i++)
    			ne[i][j] = ne[ne[i][j - 1]][j - 1];
    	printf("%d
    ", calc(-2e9, 2e9));
    	S.insert((dd){-2e9, -2e9});
    	S.insert((dd){2e9, 2e9});
    	for (i = 1; i <= n; i++)
    	{
    		set<dd>::iterator x = S.lower_bound(a[i]), y;
    		--(y = x);
    		L = y -> y;
    		r = a[i].x;
    		l = a[i].y;
    		R = x -> x;
    		if (L >= r || l >= R)
    			continue;
    		if (!(calc(L + 1, R - 1) ^ (calc(L + 1, r - 1) + calc(l + 1, R - 1) + 1)))
    		{
    			printf("%d ", i);
    			S.insert(a[i]);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    HDU4474 Yet Another Multiple Problem BFS搜索
    HDU4473 Exam 数学分析
    2013ACM多校联合(4)
    POJ1273 网络流...
    HDU4472 Count 递推
    POJ1149 PIGS 网络流
    UVA10881 Piotr's Ants 想法题
    javascript js string.Format()收集
    修改 设置 vs.net 网站 调试 设为 起始页
    【转】HTML5杂谈 概念与现行游戏 割绳子 宝石迷阵
  • 原文地址:https://www.cnblogs.com/Iowa-Battleship/p/9794672.html
Copyright © 2011-2022 走看看