1594: [Usaco2008 Jan]猜数游戏

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 556  Solved: 225

Description

为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力。 游戏开始前,一头指定的奶牛会在牛棚后面摆N(1 <= N<= 1,000,000)堆干草,每堆有若干捆,并且没有哪两堆中的草一样多。所有草堆排成一条直线,从左到右依次按1..N编号,每堆中草的捆数在1..1,000,000,000之间。 然后,游戏开始。另一头参与游戏的奶牛会问那头摆干草的奶牛 Q(1 <= Q <= 25,000)个问题,问题的格式如下: 编号为Ql..Qh(1 <= Ql <= Qh <= N)的草堆中,最小的那堆里有多少捆草? 对于每个问题,摆干草的奶牛回答一个数字A,但或许是不想让提问的奶牛那么容易地得到答案,又或许是她自己可能记错每堆中干草的捆数,总之,她的回答不保证是正确的。 请你帮助提问的奶牛判断一下,摆干草的奶牛的回答是否有自相矛盾之处。

Input

* 第1行: 2个用空格隔开的整数:N 和 Q

* 第2..Q+1行: 每行为3个用空格隔开的整数Ql、Qh、A,描述了一个问题以及它 对应的回答

Output

* 第1行: 如果摆干草的奶牛有可能完全正确地回答了这些问题(也就是说,能 找到一种使得所有回答都合理的摆放干草的方法),输出0,否则输出 1个1..Q中的数,表示这个问题的答案与它之前的那些回答有冲突之处

Sample Input

20 4
1 10 7
5 19 7
3 12 8
11 15 12

输入说明:

编号为1..10的草堆中,最小的那堆里有7捆草,编号为5..19的草堆中同样
如此;编号为3..12的草堆中最小的堆里是8捆草,11..15堆中的最小的堆里是12
捆。

Sample Output

3

输出说明:

对于第3个问题“3 12”的回答“8”与前面两个回答冲突。因为每堆中草的
捆数唯一,从前两个回答中我们能推断出,编号为5..10的干草堆中最小的那堆
里有7捆干草。很显然,第3个问题的回答与这个推断冲突。

HINT

注意:如果有冲突出现输出一个数m,使得前M-1个命题不冲突。

试题分析:首先要确定在什么情况下会出现矛盾:

      1.当存在一个(x1,y1,r)与另一个三元组(x,y,r)两个区间不相交时不存在解

      2.当存在一个(x1,y1,r1)与另一个三元组(x,y,r)中,r1>r,[x1,y1]包括[x,y],那么显然此情况不合法。

     第一个判断只需要顺次判断记录一个交集一个并集即可,第二个判断线段树维护。

     此时会发现一个问题,顺次修改并不能判断1在哪里出现矛盾或判断在2出现矛盾。

     这样我们就需要考虑二分一个答案,然后检验这个答案以及之前是否会出现矛盾。

     先离散化一下r,然后对于每个r求出其询问的交集和并集。

     然后我们就可以知道判断1只需要使用交集判断,如果一个r的询问和之前r询问的交集没有相交,那么就矛盾。

     对于判断2,从Q~1枚举r,我们的线段树只需要维护一下两个操作:

      1.查询区间与运算

      2.将一段区间置为1

     这是很好维护的,然后注意一点,取区间与需要判断的是交集,而询问中(x,y,r)相当于声明[x,y]这段区间的最小值已经是r了,那么就需要在线段树中将[x并,y并](对于询问答案r的)这一段区间置为1,而不是取交集置为1。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
inline int read(){
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const int MAXN = 1000001;
const int INF = 999999;
int N,Q;
struct data{
int x,y,r;
int id;
}a[MAXN+1];
int ans; int P[MAXN+1],cnt;
bool cmp(data a,data b){
return a.r<b.r;
}
struct row{
int x,y;
int x1,y1;
}t[MAXN+1];
int tr[MAXN*4+1];
int col[MAXN*4+1]; int mint(int a,int b){
return min((a==INF?-INF:a),(b==INF?-INF:b));
}
void Lazy_tage(int l,int r,int rt){
if(!col[rt]) return ;
tr[rt*2]=1; tr[rt*2+1]=1; tr[rt]=1;
col[rt*2]=1; col[rt*2+1]=1;
col[rt]=0;
}
int Min(int rt,int l,int r,int L,int R){
if(L<=l&&R>=r){
return tr[rt];
}
Lazy_tage(l,r,rt);
int mid=(l+r)>>1,ans=1;
if(mid>=L) ans=ans&Min(rt*2,l,mid,L,R);
if(mid<R) ans=ans&Min(rt*2+1,mid+1,r,L,R);
return ans;
}
void Add(int rt,int l,int r,int L,int R){
if(L<=l&&R>=r){
tr[rt]=1;
col[rt]=1;
return ;
}
Lazy_tage(l,r,rt);
int mid=(l+r)>>1;
if(mid>=L) Add(rt*2,l,mid,L,R);
if(mid<R) Add(rt*2+1,mid+1,r,L,R);
tr[rt]=tr[rt*2]&tr[rt*2+1];
return ;
} bool check(int k){
memset(tr,0,sizeof(tr));
memset(col,0,sizeof(col));
for(int i=1;i<=Q;i++)
t[i].x=t[i].y=-1;
for(int i=1;i<=Q;i++){
if(a[i].id>k) continue;
if(t[a[i].r].x==-1){
t[a[i].r].x=a[i].x;//x,y为并集
t[a[i].r].y=a[i].y;
t[a[i].r].x1=a[i].x;//x1,y1为交集
t[a[i].r].y1=a[i].y;
}
else{
if(a[i].x>t[a[i].r].y||a[i].y<t[a[i].r].x) return false;
t[a[i].r].x=max(t[a[i].r].x,a[i].x);
t[a[i].r].y=min(t[a[i].r].y,a[i].y);
t[a[i].r].x1=min(t[a[i].r].x1,a[i].x);
t[a[i].r].y1=max(t[a[i].r].y1,a[i].y);
}
}
for(int i=Q;i>=1;i--){
if(t[i].x!=-1){
int op=Min(1,1,N,t[i].x,t[i].y);//查询r的并集,只有并集中才可能出现r
if(op==1) return false;
Add(1,1,N,t[i].x1,t[i].y1);//这里需要将交集加上
}
}
return true;
} int main(){
N=read(),Q=read();
for(int i=1;i<=Q;i++){
a[i].x=read(); a[i].y=read();
a[i].r=read(); P[++cnt]=a[i].r;
a[i].id=i;
}
sort(P+1,P+cnt+1);
for(int i=1;i<=Q;i++) a[i].r=lower_bound(P+1,P+cnt+1,a[i].r)-P;//离散化r
sort(a+1,a+Q+1,cmp);
int l=1,r=Q;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid)) ans=mid,l=mid+1;
else r=mid-1;
}
printf("%d\n",(ans+1)%(Q+1));
}

  

 

【bzoj1594】猜数游戏的更多相关文章

  1. 【BZOJ1594】[Usaco2008 Jan]猜数游戏 二分答案+并查集

    [BZOJ1594][Usaco2008 Jan]猜数游戏 Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在 ...

  2. 【BZOJ 1594】 [Usaco2008 Jan]猜数游戏 (二分+并查集)

    1594: [Usaco2008 Jan]猜数游戏 Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在牛棚后面 ...

  3. usaco 猜数游戏

    Description 为了提高智商,锻炼思维能力,奶牛设计了一个猜数游戏.游戏开始前,贝西会在牛棚后面摆上N个数字.所有数字排成一条直线,按次序从1到N编号.每个数字在1到10^9之间,没有两个数字 ...

  4. (一)Python之猜数游戏

    猜数游戏由简如深的编码学习过程: 3次机会: print('------------------我爱鱼C工作室------------------')count=0while count < 3 ...

  5. 猜数游戏-flag的运用

    package my;import java.util.Scanner;public class MyJava {        public static void main(String[] ar ...

  6. Java课程设计——猜数游戏(201521123111 陈伟泽)

    Java课程设计--猜数游戏(201521123111 陈伟泽) 1.团队课程设计博客链接 博客作业--猜数游戏 2.个人负责模块或任务说明 Answer:一些基础界面的构造,排行榜的构造,用文件录入 ...

  7. JAVA课程设计 猜数游戏 团队

    团队名称,成员介绍 名称: 猜数游戏 成员: 网络1514 201521123086 周颖强 网络1514 201521123087蒋勃超 项目git地址 git.oschina.net/jbc113 ...

  8. BZOJ 2222: [Cqoi2006]猜数游戏【神奇的做法,傻逼题,猜结论】

    2222: [Cqoi2006]猜数游戏 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 604  Solved: 260[Submit][Status ...

  9. 从scratch到python——猜数游戏

    ` 之前讲解了从scratch到python,基于python turtle库的实现,讲解了用scratch和python turtle绘图的实现,以及让小猫动起来和当角色被单击的例子. 本节课讲继续 ...

随机推荐

  1. HDU 1070 Milk (模拟)

    题目链接 Problem Description Ignatius drinks milk everyday, now he is in the supermarket and he wants to ...

  2. HDU 1180 诡异的楼梯 (广搜)

    题目链接 Problem Description Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一 ...

  3. JS的prototype和__proto__

    一.prototype和__proto__的概念 prototype是函数的一个属性(每个函数都有一 个prototype属性),这个属性是一个指针,指向一个对象.它 是显示修改对象的原型的属性. _ ...

  4. js_跑马灯

    跑马灯?刚听到这个词的时候,脑袋第一个想到的是跑马?嗯?就是香港的那种跑马场.懂?其次就是霓虹灯了,一闪一闪的多好看. 霓虹灯?哦,那是城市的杰作,记忆中是.开往城市边缘开,把车窗都摇下来,用速度换一 ...

  5. mysql 设置字符集

    可以用:show create table table_name查看建表信息 也可用: show create database database_name查看建库信息 mysql> creat ...

  6. MNIST数据集转化为二维图片

    #coding: utf-8 from tensorflow.examples.tutorials.mnist import input_data import scipy.misc import o ...

  7. 使用 Visual Studio 部署 .NET Core 应用 ——.Net Core 部署到Ubuntu 16.04

    .Net Core 部署到Ubuntu 16.04 中的步骤 1.安装工具 1.apache 2..Net Core(dotnet-sdk-2.0) 3.Supervisor(进程管理工具,目的是服务 ...

  8. JPA注解一对多报Could not determine type for: java.util.List错误

    在原来的项目上加新功能,启动后报Caused by: org.hibernate.MappingException: Could not determine type for: java.util.L ...

  9. leetcode 之Rotate List(18)

    这题我的第一想法是用头插法,但实际上并不好做,因为每次都需要遍历最后一个.更简单的做法是将其连成环,找到相应的位置重新设头结点和尾结点.这过 有很多细节需要注意,比如K有可能是大于链表长度的,如何重新 ...

  10. linux命令(17):pwd命令

    1:查看当前工作目录的完整路径命令:pwd 2:目录连接链接时,pwd -P  显示出实际路径,而非使用连接(link)路径:pwd显示的是连接路径: [root@host-172-168-80-55 ...