洛谷 P2898 [USACO08JAN]haybale猜测Haybale Guessing 解题报告
[USACO08JAN]haybale猜测Haybale Guessing
题目描述
给一段长度为\(n\),每个位置上的数都不同的序列\(a[1\dots n]\)和\(q\)和问答,每个问答是\((x, y, r)\)代表\(\min_\limits{i=a}^ba_i= r\), 要你给出最早的有矛盾的那个问答的编号。
输入输出格式
输入格式:
Line 1: Two space-separated integers: \(N\) and \(Q\)
Lines 2..\(Q+1\): Each line contains three space-separated integers that represent a single query and its reply: \(Q_l\), \(Q_h\), and \(A\)
输出格式:
Line 1: Print the single integer \(0\) if there are no inconsistencies among the replies (i.e., if there exists a valid realization of the hay stacks that agrees with all Q queries). Otherwise, print the index from 1..Q of the earliest query whose answer is inconsistent with the answers to the queries before it.
牛客居然考原题...不过题目还是很棒的。
考虑什么情况会产生矛盾。
两段不相交的区间的最小值相同
一个最小值大的区间完全覆盖了一个最小值小的区间
一个区间被其他几个区间完全填充时的,最小值比它们都小。
直接处理很难,如果我们可以按顺序处理的话,比如按最小值从大到小排序,无疑会方便很多,但是回答本身就是带顺序的,我们不可以直接打乱它们。
怎么办呢,二分答案。这无疑是一个很棒的二分答案的思路。正确性很显然。
考虑判断前\(i\)个区间是否产生矛盾,我们按最小值从大到小排序,然后一个一个加入。
- 如果当前区间被其他区间完全覆盖,返回不合法。
- 如果当前区间与其他区间最小值相同
- 如果两个区间不交,返回不合法
- 如果两个区间有交,检查它们的交集是否被别人覆盖,拿它们的并集去覆盖别人。
检查区间覆盖可以通过线段树染色求得,只需要区间赋值\(1\)和区间求和就可以了。
Code:
#include <cstdio>
#include <algorithm>
#include <cstring>
#define rep(i,a,b) for(int i=a;i<=b;i++)
const int N=1e5+10;
int n,q,L[N],R[N],v[N];
struct node
{
int l,r,v,cl,cr;
bool friend operator <(node n1,node n2)
{
return n1.v==n2.v?n1.l<n2.l:n1.v>n2.v;
}
node(){}
node(int l,int r,int v)
{
this->l=l,this->r=r,this->v=v,this->cl=l,this->cr=r;
}
}Q[N],Q0[N];
const int M=4e6+10;
int tag[M],sum[M];
#define ls id<<1
#define rs id<<1|1
void pushdown(int id,int L,int R)
{
if(tag[id])
{
int Mid=L+R>>1;
sum[ls]=Mid+1-L,sum[rs]=R-Mid;
tag[id]=0;tag[ls]=tag[rs]=1;
}
}
int query(int id,int L,int R,int l,int r)
{
if(L==l&&R==r) return sum[id];
pushdown(id,L,R);
int Mid=L+R>>1;
if(r<=Mid) return query(ls,L,Mid,l,r);
else if(l>Mid) return query(rs,Mid+1,R,l,r);
else return query(ls,L,Mid,l,Mid)+query(rs,Mid+1,R,Mid+1,r);
}
void change(int id,int L,int R,int l,int r)
{
if(tag[id]) return;
if(L==l&&R==r)
{
sum[id]=R+1-L,tag[id]=1;
return;
}
int Mid=L+R>>1;
if(r<=Mid) change(ls,L,Mid,l,r);
else if(l>Mid) change(rs,Mid+1,R,l,r);
else change(ls,L,Mid,l,Mid),change(rs,Mid+1,R,Mid+1,r);
sum[id]=sum[ls]+sum[rs];
}
int max(int x,int y){return x>y?x:y;}
int min(int x,int y){return x<y?x:y;}
bool check(int m)
{
rep(i,1,m) Q[i]=node(L[i],R[i],v[i]);
std::sort(Q+1,Q+1+m);
int m_=0;
rep(i,1,m)
{
if(Q[i].v==Q0[m_].v)
{
if(Q0[m_].r<Q[i].l) return false;
else
{
Q0[m_].l=Q[i].l;
Q0[m_].cr=max(Q0[m_].cr,Q[i].r);
Q0[m_].r=min(Q0[m_].r,Q[i].r);
}
}
else Q0[++m_]=Q[i];
}
memset(tag,0,sizeof(tag));
memset(sum,0,sizeof(sum));
rep(i,1,m_)
{
int l=Q0[i].l,r=Q0[i].r,cl=Q0[i].l,cr=Q0[i].cr;
if(query(1,1,n,l,r)==r+1-l) return false;
change(1,1,n,cl,cr);
}
return true;
}
int main()
{
scanf("%d%d",&n,&q);
rep(i,1,q) scanf("%d%d%d",L+i,R+i,v+i);
int l=1,r=q;
if(check(q)) return puts("0"),0;
while(l<r)
{
int mid=l+r>>1;
if(check(mid)) l=mid+1;
else r=mid;
}
printf("%d\n",l);
return 0;
}
2018.10.29
洛谷 P2898 [USACO08JAN]haybale猜测Haybale Guessing 解题报告的更多相关文章
- 洛谷 P3119 [USACO15JAN]草鉴定Grass Cownoisseur 解题报告
P3119 [USACO15JAN]草鉴定Grass Cownoisseur 题目描述 约翰有\(n\)块草场,编号1到\(n\),这些草场由若干条单行道相连.奶牛贝西是美味牧草的鉴赏家,她想到达尽可 ...
- 【洛谷】CYJian的水题大赛 解题报告
点此进入比赛 \(T1\):八百标兵奔北坡 这应该是一道较水的送分题吧. 理论上来说,正解应该是DP.但是,.前缀和优化暴力就能过. 放上我比赛时打的暴力代码吧(\(hl666\)大佬说这种做法的均摊 ...
- 洛谷 P3143 [USACO16OPEN]钻石收藏家Diamond Collector 解题报告
P3143 [USACO16OPEN]钻石收藏家Diamond Collector 题目描述 Bessie the cow, always a fan of shiny objects, has ta ...
- 洛谷 P1337 [JSOI2004]平衡点 / 吊打XXX 解题报告
P1337 [JSOI2004]平衡点 / 吊打XXX 题目描述 有 \(n\) 个重物,每个重物系在一条足够长的绳子上.每条绳子自上而下穿过桌面上的洞,然后系在一起.\(X\)处就是公共的绳结.假设 ...
- 洛谷 P4151 [WC2011]最大XOR和路径 解题报告
P4151 [WC2011]最大XOR和路径 题意 求无向带权图的最大异或路径 范围 思路还是很厉害的,上午想了好一会儿都不知道怎么做 先随便求出一颗生成树,然后每条返祖边都可以出现一个环,从的路径上 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 洛谷 P2420 让我们异或吧 解题报告
P2420 让我们异或吧 题目描述 异或是一种神奇的运算,大部分人把它总结成不进位加法. 在生活中-xor运算也很常见.比如,对于一个问题的回答,是为1,否为0.那么: (A是否是男生 )xor( B ...
- 洛谷 P3102 [USACO14FEB]秘密代码Secret Code 解题报告
P3102 [USACO14FEB]秘密代码Secret Code 题目描述 Farmer John has secret message that he wants to hide from his ...
- 洛谷 P2341 [HAOI2006]受欢迎的牛 解题报告
P2341 [HAOI2006]受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的"喜欢&q ...
随机推荐
- C for阶乘
#include <stdio.h> int main(int argc, char **argv) { //定义三个变量 x n s ,n s的初始值为1; int x; i ...
- 【转载】2015Android 面试题 01
1.如何避免ANR? 答:ANR:Application Not Responding,五秒在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应. 当出现下列情况时,Andr ...
- 文件操作---基于python
# coding:utf-8from time import sleepimport sysreload(sys)sys.setdefaultencoding("utf8")f=o ...
- 【转】cpu的核心数与线程数的关系
原文地址:http://www.dn580.com/dnzs/dncs/2013/10/08/172948914.html 我们在选购电脑的时候,CPU是一个需要考虑到核心因素,因为它决定了电脑的性能 ...
- 11.22Daily Scrum
人员 任务分配完成情况 明天任务分配 王皓南 实现网页上视频浏览的功能.研究相关的代码和功能.979 数据库测试 申开亮 实现网页上视频浏览的功能.研究相关的代码和功能.978 实现视频浏览的功能 王 ...
- java实现屏幕共享的小程序
最近在做软件软件工程的课程设计,做一个用于实验室的屏幕监控系统,参考各种前人代码,最后领悟之后要转换自己的代码,初学者都是这样模仿过来的. 说到屏幕监控系统,有教师断和学生端, ...
- 20172330 2017-2018-1 《Java程序设计》第八周学习总结
学号 2017-2018-1 <程序设计与数据结构>第八周学习总结 教材学习内容总结 这一章主要是对多态性的学习: 由继承实现多态性 多态性引用能够随时间变化指向不同类型的对象. 对于多态 ...
- C++ Mooc学习
# C++远征篇之起航 1.IDE搭建,现在大部分同学都使用devC,devC的debug调试功能特别好用,可以跟踪变量.省去了在中间插入一些输出语句来输出中间变量的麻烦. 2.using names ...
- javaIO--字节流
流---是指的一组有序的.有气垫和重点的字节集合,是对的护具传输的总称或者抽象. 流采用缓冲区技术,当写一个数据时,系统将数据发送到缓冲区而不是外部设备(如硬盘),当读一个数据时,系统实际是从缓冲区读 ...
- Swift-重写(Override)
子类可以为继承来的实例方法(instance method),类方法(class method),实例属性(instance property),或附属脚本(subscript)提供自己定制的实现(i ...