【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:一些基础界面的构造,排行榜的构造,用文件录入 ...
随机推荐
- 《JavaScript 高级程序设计》总结
一.JS基本概念 1.命名规则 变量名区分大小写(test和Test是两个不同的变量名),标识符采用驼峰命名格式,即:第一个字母小写,剩下的每个有意义的单词首字母大写: 标识符第一个字符必须是以字母. ...
- Python 循环语句和运算符
while 循环 while 条件 : //条件为True时,执行while下带有缩进的语句 语句1 语句2 语句3 for循环 for循环可以用来遍历某一对象(遍历:通俗点说,就是把这个循环中的第一 ...
- TCP系列28—窗口管理&流控—2、延迟ACK(Delayed Acknowledgments)
一.简介 之前的内容中我们多次提到延迟ACK(Delayed Ack),延迟ACK是在RFC1122协议中定义的,协议指出,一个TCP实现应该实现延迟ACK,但是ACK不能被过度延迟,协议给出延迟AC ...
- 数据库性能优化之SQL优化
网上有关SQL优化的方案有很多,但多是杂乱无章.近日闲暇抽空整理了一下,方便大家以后的查阅,若发现其中有什么问题和不全,欢迎大家在下面纠正和补充: 1. 对于SQL语句的性能优化,主要体现在对于查询语 ...
- PAT L1-039 古风排版
https://pintia.cn/problem-sets/994805046380707840/problems/994805091888906240 中国的古人写文字,是从右向左竖向排版的.本题 ...
- Python运算符与编码
阅读目录 while 循环 运算符 编码的问题 单位转换 整数 布尔值 while 循环 在生活中,我们遇到过循环的事情吧?比如循环听歌.在程序中,也是存才的,这就是流程控制语句 while 1.基本 ...
- 在网页中浏览PDF文档
刚开始找了好多插件,包括pdf.js,但都不理想,后来发现用iframe反而容易: <iframe src="test_pdf.pdf" width="800&qu ...
- .Net MVC 实现长轮询
什么是长轮询? 长轮询是“服务器推”技术实现方式的一种,可以将服务端发生的变化实时传送到客户端而无须客户端频繁的地刷新.发送请求. 长轮询原理? 客户端向服务器发送Ajax请求,服务器接收到请求后,保 ...
- hdu 1054 Strategic Game (二分匹配)
Strategic Game Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Codeforces Gym 101142 G Gangsters in Central City (lca+dfs序+树状数组+set)
题意: 树的根节点为水源,编号为 1 .给定编号为 2, 3, 4, …, n 的点的父节点.已知只有叶子节点都是房子. 有 q 个操作,每个操作可以是下列两者之一: + v ,表示编号为 v 的房子 ...