【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:一些基础界面的构造,排行榜的构造,用文件录入 ...
随机推荐
- 【Linux】- 不可不知的小技巧
1.Tab键:输入文件或目录名的前几个字符,然后按TAB键,如无相重的,完整的文件名立即自动在命令行出现:如有相重的,再按一下TAB键,系统会列出当前目录下所有以这几个字符开头的名字. 在命令行下,只 ...
- shell练习题讲解
写一个脚本,计算100以内所有的奇数的和以及所有偶数的和,分别显示出来#! /bin/bashsum1=0for i in `seq 1 2 100`do sum1=$[$sum1+$i]doneec ...
- java 基础--继承--007
1,子类只能继承父类所有非私有成员 2,子类不能继承父类的构造方法,但可以通过super去访问父类构造方法 3,子类成员变量和父类成员变量名称不一样,如果一样类似于重写,按子类处理,如果一样,就近原则 ...
- Keil MDK中Image~~RW_IRAM1~~ZI~~Limit(~表示$)
ARM程序的组成 此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的bin映像(image)文件,这一点清注意区别. 一个ARM程序包含3部分:RO, ...
- 获取当前路径下的所有文件路径 :listFiles
获取当前路径下的所有文件路口 :listFiles
- poj3164-Command Network
给出平面上一些点,和连接它们的带权有向边,求把所有点连起来的最小总权值. 分析 由于这里边是有向的(unidirectional),所以这是经典的最小树形图问题,可以说是最小树形图的模板题. 代码 这 ...
- 【bzoj1507】[NOI2003]Editor /【bzoj1269】[AHOI2006]文本编辑器editor Splay
[bzoj1507][NOI2003]Editor 题目描述 输入 输入文件editor.in的第一行是指令条数t,以下是需要执行的t个操作.其中: 为了使输入文件便于阅读,Insert操作的字符串中 ...
- 【bzoj1131】[POI2008]Sta 树形dp
题目描述 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 输入 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. 输出 输出你所找到的点,如果具有 ...
- Gevent-自动挡切换
Gevent: Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程. G ...
- 蒟蒻Orion还要学的东西!
这个ID多元化真是个麻烦的事情...... 一会KamijouIndex一会dedicatus545一会Orion的,乱死了啊啊啊啊 数据结构 圆方树 ETT 仙人掌 可持久化树套树 数学 洲阁筛 m ...