参考文献:题解 P2898 【[USACO08JAN]haybale猜测Haybale Guessing】 - レムの小屋 - 洛谷博客

题目链接:[USACO08JAN]Haybale Guessing G - 洛谷

分析:

首先想一下矛盾的情况有哪些?

 此两种情况会产生矛盾,

第二条的话就判断两个无交集的区间是否有相同的最小值,有的话那么一定是错的。

第一条的话可以从大到小的方式求解区间,如果当前所求的区间在之前已经求过的话,那么这个区间之前已经确定了一个更大的值,那么当前区间和之前确定的区间之间就会存在矛盾。

同时,对于这种第一个出现问题的情况,我们可以想想看是否可以使用二分的方式得到答案。

如果后面是错的,那么我们一定可以去往前面找是否有错误,这就说明了他们是单调的。可以使用二分。

同时,了解到二分时候的l == r == mid的含义是 l,r,mid这个时候是正确的时候,所以第一个错误的情况就是 l + 1。

代码实现:

# include <iostream>
# include <cstring>
# include <algorithm>
using namespace std;const int N = 1e6 + 10;int n,q;struct tt
{int l,r,v;
}tr[N],tr2[N];struct Node
{int l,r;int sum;int lz; // 懒标记
}edgs[N * 4];bool cmp(struct tt a , struct tt b) // 从大到小排
{return a.v > b.v;
}void pushup(int u)
{edgs[u].sum = edgs[2 * u].sum + edgs[2 * u + 1].sum;
}void pushdown(int u)
{if(edgs[u].lz){edgs[2 * u].lz = edgs[u].lz;edgs[2 * u].sum = (edgs[u * 2].r - edgs[u * 2].l + 1) * edgs[u].lz; // edgs[2 * u]的所有区间都被用过了edgs[2 * u +1].lz = edgs[u].lz;edgs[2 * u + 1].sum = (edgs[2 * u + 1].r - edgs[2 * u +1].l + 1) * edgs[u].lz;edgs[u].lz = 0;}
}void build(int u , int l , int r)
{edgs[u].l = l;edgs[u].r = r;if(l == r){return;}else{int mid = (edgs[u].l + edgs[u].r) / 2;build(2 * u , l ,mid);build(2 * u + 1 , mid + 1 , r);return;}
}void modify(int u , int l , int r , int v)
{if(l <= edgs[u].l && edgs[u].r <= r){edgs[u].sum = (edgs[u].r - edgs[u].l + 1) * v;edgs[u].lz = v;}else{pushdown(u);int mid = ( edgs[u].l + edgs[u].r ) / 2;if(l <= mid){modify(2 * u , l , r , v);}if(r > mid){modify(2 * u + 1 , l , r , v);}pushup(u);}
}int query(int u , int l , int r)
{if(l <= edgs[u].l && edgs[u].r <= r){return edgs[u].sum;}else{pushdown(u);int mid = ( edgs[u].l + edgs[u].r ) / 2;int ans = 0;if(l <= mid){ans += query(2 * u , l , r);}if(r > mid){ans += query(2 * u + 1 , l , r);}return ans;}
}bool check(int x)
{memset(edgs,0,sizeof edgs);build(1,1,n);for(int i = 1 ; i <= q ; i++){tr2[i] = tr[i];}sort(tr2 + 1 , tr2 + x + 1,cmp); // 将x个从大值到小值进行排序for(int i = 1 ; i <= x ; ){int j = i; // j找到第一个比i值的v小的值while(j <= x && tr2[j].v == tr2[i].v){j++;}//i ~ j - 1位置上的所有值都是相等的,求这个区间的 并集 和 交集int ul,ur,cl,cr; // ul,ur代表者并集的左右区间,cl和cr代表着交集的左右区间ul = cl = tr2[i].l;ur = cr = tr2[i].r;for(int k = i; k < j ; k++){ul = min(ul,tr2[k].l);ur = max(ur,tr2[k].r);cl = max(cl,tr2[k].l);cr = min(cr,tr2[k].r);}if(cr < cl) // 交集为空,说明有两个不是在一个交集的有相同的最小值,这是错误的{return false;}if(query(1,cl,cr) == cr - cl + 1) // 如果前面大值已经将cr - cl + 1 覆盖了,那么现在的小值的区间就会与前面的重复,是错误的{return false;}modify(1,ul,ur,1); // 区间修改,cl~cr区间全部改为1i = j;}return true;
}int main()
{scanf("%d %d",&n,&q);for(int i = 1 ; i <= q ; i++){int l,r,x;scanf("%d %d %d",&l,&r,&x);tr[i] = {l,r,x};}int l = 1 , r = q; // 可能q个都对while(l < r){int mid = (l + r + 1) / 2;  // 第mid个说了假话if(check(mid)) // 如果成立的话,{l = mid;}else{r = mid - 1;}}// l和r为最后一个正确的if(r == q) // 都正确,返回0.{printf("%d\n",0);}else    printf("%d\n",r + 1);return 0;
}

线段树 + 二分答案:Haybale Guessing G相关推荐

  1. bzoj 4743: [Usaco2016 Dec]Robotic Cow Herd 线段树+二分答案

    题意 有n个数集,每个数集里最多只有10个元素,现在从每个数集里面选数一个数,假设选出的数的和是p,给出k,问前k小的p的和. n,k<=100000 分析 首先二分答案lim,然后考虑如何找到 ...

  2. 牛客小白月赛28 E-会当凌绝顶,一览众山小 线段树+二分暴力模拟

    牛客小白月赛28 E-会当凌绝顶,一览众山小 线段树+二分暴力模拟 题意 思路 Code 传送门: https://ac.nowcoder.com/acm/contest/16081/E 题意 登山顺 ...

  3. codeforces 609F Frogs and mosquitoes 线段树+二分+multiset

    http://codeforces.com/problemset/problem/609/F There are n frogs sitting on the coordinate axis Ox. ...

  4. [ZJOI2015] 幻想乡战略游戏(树链剖分 + 线段树二分 + 带权重心)

    problem luogu-P3345 solution 这是一个带权重心的题,考察动态点分治.点分治?呵,不可能的,这辈子都不可能写点分治 我们重新考虑重心的性质:以这个点为根时,所有子树的大小不会 ...

  5. CodeForces - 1454F Array Partition(线段树+二分)

    题目链接:点击查看 题目大意:给出一个长度为 n 的序列,现在要求求出任意一组 x , y , z,满足下列条件: x + y + z = n max( 1 , x ) = min( x + 1 , ...

  6. P2824-[HEOI2016/TJOI2016]排序【线段树,二分】

    正题 题目链接:https://www.luogu.com.cn/problem/P2824 题目大意 nnn个数,每次将一个区间正序或者倒序排序,求最后位置ppp的数. 解题思路 思路确实巧妙 二分 ...

  7. 【Codeforces】WHU校赛2019 Store(线段树+二分)

    题目链接 C. Store time limit per test 1.0 s memory limit per test 256 MB input standard input output sta ...

  8. Codeforces Round #807 (Div. 2) E. Mark and Professor Koro(线段树二分)

    E. Mark and Professor Koro 题意 给定一个长度为n的数组,有q次更新操作,每次更新会将下标为k的元素的值更新为l,数组的更新是永久的.将数组更新后假设重复做以下操作,求可以得 ...

  9. HDU - 4614 Vases and Flowers 线段树+二分

    题目链接 思路:线段树维护区间和,当k=1时,询问二分询问[x-(x~n-1)]找到最小位置,复杂度n*logn*logn卡过 #include<stdio.h> #include< ...

最新文章

  1. MySQL数据库order by 奇慢无比
  2. iPhone是否越狱的检测方法
  3. 自定义搜索框,带提示信息的搜索框
  4. Android 自动判断是电话,网址,EMAIL方法之Linkify
  5. Codeforces 165D Beard Graph 边权树剖+树状数组
  6. 『Asp.Net 组件』Asp.Net 服务器组件 内嵌CSS:将CSS封装到程序集中
  7. Shader编程教程_Shader新手入门视频教程_Shader编程从入门到精通
  8. Linux压缩、解压、打包文件 修改文件所属组
  9. 模仿百思不得姐项目笔记
  10. 编写python程序、计算账户余额_《易学Python》——第1章 为何学习Python 1.1 学习编程...
  11. 为什么北半球的旋涡都是逆时针的
  12. 免费的播放器软件--mpv
  13. flinksql实时读取kafka写入mysql
  14. 小程序用户头像昵称获取不到解决办法
  15. Java 判断年份是闰年还是平年
  16. 鸿蒙系统开发实战-开发一个聊天技巧软件堪称聊天神器
  17. 【IPTV】Hybrid Video解决方案概念与价值
  18. 全球30米地表覆盖遥感制图关键技术与产品研发
  19. 使用网络摄像头在 Python 中进行人脸检测
  20. [已迁移]pwn-2021东华杯-部分[cpp1,gcc2,bg3]

热门文章

  1. 苹果13mini和苹果13参数对比选哪个 苹果13mini和苹果13的区别
  2. 六边形算法java_六边形架构 Java 实现
  3. CTF_Web:攻防世界高手区进阶题WP(15-18)
  4. 事件A和B之间相互独立与互不相容的理解
  5. 中级财管电脑操作不会用计算机,很全面!2018年中级无纸化考试财管公式输入方法及计算器操作说明...
  6. 编译原理:了解编译原理
  7. 华为MateBook E 12.6英寸 win11 16g+512g 轻评测
  8. ThinkPHP 虚拟主机 跳转public主页设置
  9. 如何把华为数据分析项目写进简历
  10. VC/MFC使用OLE操作 EXCEL