zoukankan      html  css  js  c++  java
  • [BZOJ2811][Apio2012]Guard

    [BZOJ2811][Apio2012]Guard

    试题描述

    输入

    输出

    输入示例

    5 3 4
    1 2 1
    3 4 1
    4 4 0
    4 5 1

    输出示例

    3
    5

    数据规模及约定

    见“试题描述

    题解

    首先 Ci = 0 的区间必定都为 0,打个离线标记啥的把该标 0 的标成 0,看剩下的 1 的个数是否为 K,如果是那么所有的位置都是必填的。

    考虑剩下的情况,我们给 1 的位置重新标号,区间也对应重新标号一下,把包含了其他区间的区间删除,然后正反贪心一波。令 f[i] 表示前 i 个区间至少需要多少个点,g[i] 表示后 N-i+1 个区间至少需要几个点(N 表示区间个数);依次检查每个区间的右端点(设它为 x)是否能够被 x-1 取代,方法是二分找到 x-1 能够管道的区间都有哪些,设这些区间的编号为 [l, r],那么 f[l-1] + 1 + g[r+1] > K 的时候 x 就不能被取代。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    
    int read() {
    	int x = 0, f = 1; char c = getchar();
    	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    	return x * f;
    }
    
    #define maxn 100010
    #define maxlog 17
    
    int n, m, K, tag[maxn], A[maxn], S[maxn], id[maxn], lst[maxn], lstr[maxn], cntl;
    struct Line {
    	int l, r;
    	Line() {}
    	Line(int _, int __): l(_), r(__) {}
    	bool operator < (const Line& t) const { return r != t.r ? r < t.r : l > t.l; }
    } ls[maxn];
    bool has[maxn];
    
    int f[maxn], g[maxn], pos[maxn];
    
    int main() {
    	n = read(); K = read(); m = read();
    	for(int i = 1; i <= m; i++) {
    		int l = read(), r = read(), tp = read();
    		if(tp) ls[++cntl] = Line(l, r);
    		else tag[l]++, tag[r+1]--;
    	}
    	
    	int now = 0, lst1 = 0, cnt = 0;
    	for(int i = 1; i <= n; i++) {
    		now += tag[i];
    		if(now) A[i] = 0; else A[i] = 1;
    		cnt += A[i];
    		if(A[i]) id[i] = id[lst1] + 1, pos[id[i]] = i;
    		if(A[i]) lst1 = i; lst[i] = lst1;
    	}
    //	for(int i = 1; i <= n; i++) printf("%d%c", id[i], i < n ? ' ' : '
    ');
    	lst1 = n + 1;
    	for(int i = n; i; i--) {
    		if(A[i]) lst1 = i; lstr[i] = lst1;
    	}
    	
    	if(!cnt) return puts("-1"), 0;
    	if(cnt == K) {
    		for(int i = 1; i <= n; i++) if(A[i]) printf("%d
    ", i);
    		return 0;
    	}
    	
    	for(int i = 1; i <= cntl; i++) ls[i].l = id[lstr[ls[i].l]], ls[i].r = id[lst[ls[i].r]];
    	sort(ls + 1, ls + cntl + 1);
    	int tc = cntl; cntl = 0;
    	for(int i = 1; i <= tc;) {
    		int j = i + 1;
    		ls[++cntl] = ls[i];
    		while(ls[j].l <= ls[i].l && ls[i].r <= ls[j].r) j++;
    		i = j;
    	}
    //	for(int i = 1; i <= cntl; i++) printf("[%d, %d]
    ", ls[i].l, ls[i].r);
    	for(int i = 1; i <= cntl;) {
    		int j = i + 1; has[i] = 1; f[i] = f[i-1] + 1;
    		while(j <= cntl && ls[j].l <= ls[i].r && ls[i].r <= ls[j].r) f[j++] = f[i];
    		i = j;
    	}
    	for(int i = cntl; i;) {
    		int j = i - 1; g[i] = g[i+1] + 1;
    		while(j && ls[j].l <= ls[i].l && ls[i].l <= ls[j].r) g[j--] = g[i];
    		i = j;
    	}
    //	puts("here");
    	bool ok = 0;
    	for(int i = 1; i <= cntl; i++) if(has[i]) {
    		if(ls[i].l == ls[i].r) {
    			printf("%d
    ", pos[ls[i].l]); ok = 1;
    			continue;
    		}
    		int x = ls[i].r - 1, l = 1, r = i, L, R;
    		while(l < r) {
    			int mid = l + r >> 1;
    			if(ls[mid].r < x) l = mid + 1; else r = mid;
    		}
    		L = l;
    		l = i; r = cntl + 1;
    		while(r - l > 1) {
    			int mid = l + r >> 1;
    			if(ls[mid].l > x) r = mid; else l = mid;
    		}
    		R = l;
    		if(f[L-1] + 1 + g[R+1] > K) printf("%d
    ", pos[ls[i].r]), ok = 1;
    	}
    	
    	if(!ok) puts("-1");
    	
    	return 0;
    }
    
  • 相关阅读:
    火狐浏览器插件开发工具
    MyEclipse设置JSP页面默认编码方式
    如何让editplus保存时不生成.bak备份文件
    Sublime Text 2 使用心得
    火狐浏览器的一些常用设置
    能帮你提高工作效率的10个在线工具
    如何治疗颈椎病
    企业架构研究总结(2)——问题的由来和基本概念
    企业架构研究总结(1)——参考资料列表
    企业架构研究总结(4)——企业架构与企业架构框架概论
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/6645214.html
Copyright © 2011-2022 走看看