[洛谷P2898][USACO08JAN]haybale猜测Haybale Guessing
来源:互联网 发布:注册域名不需要实名 编辑:程序博客网 时间:2024/06/05 18:25
题目←
题意:
总共有n个互不相同的正整数,LYK每次猜一段区间的最小值。形如[li,ri]这段区间的数字的最小值一定等于xi。
我们总能构造出一种方案使得LYK满意。直到…… LYK自己猜的就是矛盾的!
例如LYK猜[1,3]的最小值是2,[1,4]的最小值是3,这显然就是矛盾的。
你需要告诉LYK,它第几次猜数字开始就已经矛盾了。
10^5~10^6数据范围,容易考虑nlogn
这个log就来自二分了……
1、一段区间被最小值比他大的区间完全包含的时候
2、n个数互不相同,所以当两个无交集的区间最小值相同时一定矛盾
我们发现,当遇到一段最小值比当前区间小的区间时,只要不被当前区间完全包含就构不成矛盾情况
而当前区间能更新最小值的部分也仅限于不被最小值较小的区间包含的部分
所以按最小值从大到小处理,这样就不用划分分区间了……
用并查集维护区间染色情况
因为从大到小处理,之前染过的颜色一定比当前最小值大
故发现当前区间被完全染色时一定矛盾
至于情况二,只会在最小值相同的猜测中出现
而排了序之后他们是相邻的
到时候判断一下交集就好了
注意最小值相同的区间的处理,合并时合并最大范围,判断时最小范围(实际存在区间)
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 2000000 + 50;int fa[MAXN],rank[MAXN];int find(int x){ return fa[x] == x ? x : fa[x] = find(fa[x]);}struct px{ int l,r,z;}B[MAXN << 1],t[MAXN << 1];inline int read(){ int x = 0, f = 1; char ch = getchar(); for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; return x * f;}int n,m;bool cmp(px a,px b){ return a.z > b.z;}bool solve[MAXN];bool check(int k){ for(int i = 1;i <= n + 1;i ++){//会访问到fa[n + 1] fa[i] = i; } for(int i = 1;i <= k;i ++){ t[i] = B[i]; } sort(t + 1,t + k + 1,cmp); int l,r,liml,limr; l = liml = t[1].l; r = limr = t[1].r; t[k + 1].l = 0; t[k + 1].r = n + 1; for(int i = 2;i <= k + 1;i ++){ while(t[i].z == t[i - 1].z){ l = min(l,t[i].l); r = max(r,t[i].r); liml = max(liml,t[i].l); limr = min(limr,t[i].r); if(liml > limr)return false; i ++; if(i > k)break; } if(find(liml) > limr)return false; for(int j = l;j <= r;j ++){ j = find(j); fa[j] = find(r + 1); } l = liml = t[i].l; r = limr = t[i].r; } return true;}int L = 1,R;int main(){ n = read(); m = read(); for(int i = 1;i <= m;i ++){ B[i].l = read(); B[i].r = read(); B[i].z = read(); } R = m + 1; while(R - L > 1){ int mid = L + R >> 1; if(check(mid))L = mid; else R = mid; } if(R == m + 1)R = 0; printf("%d",R);}
这题考试时限是2s,但洛谷只有1s……
其实区别在这一段
for(int j = l;j <= r;j ++){ j = find(j); fa[j] = find(r + 1); }
std代码是
for(j = find(lmin); j <= rmax; j++) f[find(j)] = find(rmax + 1);
多跑了很多已经合并过的区间
阅读全文
0 0
- [洛谷P2898][USACO08JAN]haybale猜测Haybale Guessing
- 洛谷 2898 [USACO08JAN]haybale猜测Haybale Guessing
- 【洛谷 2898】 [USACO08JAN]haybale猜测Haybale Guessing
- 洛谷P2898haybale猜测Haybale Guessing
- POJ3657.Haybale Guessing
- POJ Haybale Guessing
- POJ 3657 Haybale Guessing 笔记
- POJ 3657 Haybale Guessing 并查集+二分答案
- bzoj1594[Usaco2008 Jan]Haybale Guessing猜数游戏
- POJ 3657/bzoj 1594 猜数游戏 Haybale Guessing
- 【USACO】2008 Jan Haybale Guessing 猜数游戏
- Poj 3657 Haybale Guessing(二分+并查集)
- Poj 3657 Haybale Guessing(二分+并查集)
- 【POJ3657】【USACO 2008 Jan Gold】 1.Haybale Guessing 二分答案,并查集check
- bzoj2620[Usaco2012 Mar]Haybale Restacking
- USACO 2012 Mar Haybale Restacking 重排干草
- 【USACO08JAN】洛谷1948 Telephone Lines
- 洛谷p2419[USACO08JAN]牛大赛Cow Contest
- Java数据结构与算法解析(十二)——散列表
- TensorFlow学习日记22
- 【廖雪峰Python习题集】使用list和tuple
- 那些年错过的蓝桥杯(五)
- Java数据结构与算法解析(十三)——优先级队列
- [洛谷P2898][USACO08JAN]haybale猜测Haybale Guessing
- 花店橱窗布置
- 异常处理
- Java字符串处理String、StringBuilder、StringBuffer类效率分析
- WebSphere下配置 Oracle XA数据源
- 推荐一个pdf转换成excel的方法
- 设置下拉框选中的值
- js回调函数
- 2011NOIP普级组第一题--数字反转