【bzoj1594-猜数游戏】线段树

题解:
矛盾只有两种情况:
一.先前确定了x在区间(l,r),但是现在发现x在区间(l1,r1),并且两个区间不相交。
二.一个区间的最小值是x,这个区间中有一个子区间的最小值比x更小。
首先可以明确,对于每个x,我们可以不断地缩小x的范围(取区间的交集)。
那就先处理第一种矛盾,假设第一种矛盾第一次出现是在信息i。
那么我们就在信息1~i中寻找是否有第二种矛盾(此时保证了1~i中不会有第一种矛盾)。

每个信息有l,r,d三个值,我们按照d排序。那就在扫到下面那个区间的时候,我们一定已经有了上面的区间。
然后我们在线段树里面看红色的这个区间是否已经被完整地覆盖了。
线段树每个节点维护覆盖这个节点的最前面一个信息(因为题目要求最前的信息)。
如果红色区间被多个区间加在一起完整覆盖,那我们要去这多个区间的信息的max值(必须等到它也出现了才能完整覆盖)
最后维护一下ans。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<ctime>
#include<queue>
#include<algorithm>
using namespace std; const int N=,INF=(int)1e9;
struct node{int l,r,lc,rc,id,lazy;}t[*N];
struct nod{int d,id;}p[N];
struct nd{int l,r,d,id;}q[N];
int n,m,tl,L[N],R[N]; bool cmp_nod(nod x,nod y){return x.d<y.d;}
bool cmp_nd(nd x,nd y)
{
if(x.d!=y.d) return x.d>y.d;
return x.id<y.id;
}
int minn(int x,int y){return x<y ? x:y;}
int maxx(int x,int y){return x>y ? x:y;} int buildtree(int l,int r)
{
int x=++tl;
t[x].l=l;t[x].r=r;
t[x].lc=t[x].rc=;
t[x].id=INF;t[x].lazy=INF;
if(l<r)
{
int mid=(l+r)/;
t[x].lc=buildtree(l,mid);
t[x].rc=buildtree(mid+,r);
}
return x;
} void upd(int x)
{
if(t[x].lazy==INF) return ;
int id=t[x].lazy,lc=t[x].lc,rc=t[x].rc;
t[x].lazy=INF;
t[x].id=minn(t[x].id,id);
if(lc) t[lc].lazy=minn(t[lc].lazy,id);
if(rc) t[rc].lazy=minn(t[rc].lazy,id);
} void change(int x,int l,int r,int id)
{
upd(x);
if(t[x].l==l && t[x].r==r)
{
t[x].lazy=minn(t[x].lazy,id);
upd(x);
return ;
}
int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/;
if(r<=mid) change(lc,l,r,id);
else if(l>mid) change(rc,l,r,id);
else
{
change(lc,l,mid,id);
change(rc,mid+,r,id);
}
int now=maxx(t[lc].id,t[rc].id);
if(now<INF) t[x].id=now;//debug 一个小区间都被覆盖了,大区间也会被覆盖。
} int query(int x,int l,int r)
{
upd(x);
if(t[x].l==l && t[x].r==r) return t[x].id;
int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/;
if(r<=mid) return query(lc,l,r);
else if(l>mid) return query(rc,l,r);
else return maxx(query(lc,l,mid),query(rc,mid+,r));
} int main()
{
// freopen("a.in","r",stdin);
freopen("bales.in","r",stdin);
freopen("bales.out","w",stdout);
scanf("%d%d",&n,&m);
tl=;
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].d);
q[i].id=i;
p[i].d=q[i].d;p[i].id=i;
}
sort(p+,p++m,cmp_nod);
int mx=;p[].d=;
for(int i=;i<=m;i++)
{
if(p[i].d!=p[i-].d) mx++;
q[p[i].id].d=mx;
}
for(int i=;i<=mx;i++) L[i]=,R[i]=n;
int ans=INF;
for(int i=;i<=m;i++)
{
int x=q[i].d;
if(q[i].l>R[x] || q[i].r<L[x]) {ans=i;m=i-;break;}
L[x]=maxx(L[x],q[i].l);
R[x]=minn(R[x],q[i].r);
}
// printf("%d\n",ans);
buildtree(,n);
sort(q+,q++m,cmp_nd);
for(int i=;i<=mx;i++) L[i]=,R[i]=n;
int x,now,j=;
for(int i=;i<=m;i++)
{
while(j<i && q[j].d!=q[i].d)
{
change(,q[j].l,q[j].r,q[j].id);
j++;
}
x=q[i].d;
L[x]=maxx(L[x],q[i].l);
R[x]=minn(R[x],q[i].r);
now=query(,L[x],R[x]);
ans=minn(ans,maxx(q[i].id,now));
}
if(ans<INF) printf("%d\n",ans);
else printf("0\n");
return ;
}
【bzoj1594-猜数游戏】线段树的更多相关文章
- BZOJ 1594: [Usaco2008 Jan]猜数游戏 线段树 + 思维 + 二分
Code: #include<bits/stdc++.h> #define maxn 3000000 using namespace std; void setIO(string s) { ...
- BZOJ 1594 [Usaco2008 Jan]猜数游戏(线段数)
1594: [Usaco2008 Jan]猜数游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 626 Solved: 260[Submit][S ...
- bzoj 1594: [Usaco2008 Jan]猜数游戏——二分+线段树
Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在牛棚后面摆N(1 <= N<= 1,000,00 ...
- 【BZOJ1594】[Usaco2008 Jan]猜数游戏 二分答案+并查集
[BZOJ1594][Usaco2008 Jan]猜数游戏 Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在 ...
- 【bzoj1594】猜数游戏
1594: [Usaco2008 Jan]猜数游戏 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 556 Solved: 225 Descripti ...
- 【BZOJ 1594】 [Usaco2008 Jan]猜数游戏 (二分+并查集)
1594: [Usaco2008 Jan]猜数游戏 Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在牛棚后面 ...
- usaco 猜数游戏
Description 为了提高智商,锻炼思维能力,奶牛设计了一个猜数游戏.游戏开始前,贝西会在牛棚后面摆上N个数字.所有数字排成一条直线,按次序从1到N编号.每个数字在1到10^9之间,没有两个数字 ...
- (一)Python之猜数游戏
猜数游戏由简如深的编码学习过程: 3次机会: print('------------------我爱鱼C工作室------------------')count=0while count < 3 ...
- 猜数游戏-flag的运用
package my;import java.util.Scanner;public class MyJava { public static void main(String[] ar ...
- Java课程设计——猜数游戏(201521123111 陈伟泽)
Java课程设计--猜数游戏(201521123111 陈伟泽) 1.团队课程设计博客链接 博客作业--猜数游戏 2.个人负责模块或任务说明 Answer:一些基础界面的构造,排行榜的构造,用文件录入 ...
随机推荐
- Android 开发 之 JNI入门 - NDK从入门到精通
NDK项目源码地址 : -- 第一个JNI示例程序下载 : GitHub - https://github.com/han1202012/NDKHelloworld.git -- Java传递参数给C ...
- HDU 5816 Hearthstone 概率dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5816 Hearthstone Time Limit: 2000/1000 MS (Java/Othe ...
- 【Linux】- ps -ef |grep 命令
ps:将某个进程显示出来 grep:查找 |:管道命令 表示ps命令与grep同时执行 PS是LINUX下最常用的也是非常强大的进程查看命令 grep命令是查找,是一种强大的文本搜索工具,它能使用正则 ...
- Maven 生命周期 和插件
1.3 生命周期1.3.1 什么是生命周期? Maven生命周期就是为了对所有的构建过程进行抽象和统一.包括项目清理.初始化.编译.打包.测试.部署等几乎所有构建步骤. 生命周期可以理解为构建工程的步 ...
- Java 多线程 三种实现方式
Java多线程实现方式主要有三种:继承Thread类.实现Runnable接口.使用ExecutorService.Callable.Future实现有返回结果的多线程.其中前两种方式线程执行完后都没 ...
- 深入理解java内置锁(synchronized)和显式锁(ReentrantLock)
多线程编程中,当代码需要同步时我们会用到锁.Java为我们提供了内置锁(synchronized)和显式锁(ReentrantLock)两种同步方式.显式锁是JDK1.5引入的,这两种锁有什么异同呢? ...
- BZOJ4011 HNOI2015落忆枫音(动态规划+拓扑排序)
DAG中每个点选一条入边就可以构成一棵有向树,所以如果没有环答案就是∏degreei. 考虑去掉含环的答案.可以看做把环缩点,剩下的点仍然可以任意选入边.于是去除的方案数即为∏degreei/∏deg ...
- mysql 迁移 mariadb
背景: mysql5.7数据库安装在windows环境中,数据需要迁移到CentOS7.4的mariadb5.5中.web应用是采用springboot2.x开发的,迁移数据完成后,还需要简单修改一些 ...
- 源码安装和yum安装的区别。
yum是将yum源中别人已经编译好的rpm包下载到本地,然后安装,不需要考虑依赖,主要是方便.源码安装没法人为的控制,安装的版本也很低. 源码安装需要自己编译,安装,编译过程中可以设置参数.可安装的版 ...
- IE9的大css文件截断问题
最近做项目调试IE9的兼容性,遇到问题,样式应用不上去,在其他浏览器中是正常的. 经过查找,判定是IE9的css截断问题. 1. IE9截断判定方法 1. 打开IE Developer Tools,在 ...