二分答案(二分没冲突的前Q-1个问题),用并查集判定(用法同bzoj 1576)

  假设一个询问区间[l,r],最小干草堆数目是A,我们可以得出[l,r]上的干草堆数目都>=A。

  二分出mid后,把1~mid个询问按照最小干草数量A降序排序。。如果这些询问的回答自相矛盾的话,就存在一个询问区间[l,r],它的每个位置都存在于之前的询问区间(指那些A值比当前A值大的区间)中。也就是说根据以前的询问我们得出[l,r]里面任何一堆干草数目都大于当前的A值,那就自相矛盾了。(注意如果多个区间A值相同的话就取交集。

  就变成判断一段区间是否已被完全覆盖。。那就可以上并查集了。fa[i]表示i点所在的被覆盖的区间的左端点。

  这样的话是O(nlogQ*alpha(n))的。。我们可以离散化一下。。因为只要知道当前区间中是否存在一个点没被覆盖过,所以只要从离散化后相邻两个值中多拿出一个点做代表就行了(前提是相邻的差值>1)。这样就只剩4*Q堆干草了。

  卡了半天常。。

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=;
struct zs{
int l,r,id,mn;
}q[];
int fa[],now[],map[],L[],R[],mp[];
int j,k,n,m,l,r,mid,tot,premx,mnx,mny,mxx,mxy;
bool flag;
int ra;char rx;
inline int read(){
rx=getchar();ra=;
while(rx<''||rx>'')rx=getchar();
while(rx>=''&&rx<='')ra*=,ra+=rx-,rx=getchar();return ra;
}
bool cmp(zs a,zs b){return a.mn>b.mn;}
inline bool can(int x){
register int i,j,k;now[]=;
for(i=;i<=m;i++)if(q[i].id<=x)L[++now[]]=q[i].l,R[now[]]=q[i].r,now[now[]]=i;
memset(fa,,(premx+)<<);premx=;
for(i=;i<=now[];i=j+){
for(j=i;j<now[]&&q[now[j+]].mn==q[now[i]].mn;j++);
mnx=mny=tot;mxx=mxy=;
for(k=i;k<=j;k++){
if(L[k]<mnx)mnx=L[k];if(L[k]>mxx)mxx=L[k];if(R[k]<mny)mny=R[k];if(R[k]>mxy)mxy=R[k];
}
for(flag=,k=mny;k>=mxx;k=fa[k]-)
if(!fa[k]){flag=;break;}
if(!flag)return ;
if(mxy>premx)premx=mxy;
for(k=mxy;k>=mnx;k--)
if(!fa[k])fa[k]=mnx;
else{k=fa[k];if(k>=mnx)fa[k]=mnx;}
}
return ;
}
inline int get(int x){
l=;r=tot;
while(l<r){
mid=(l+r+)>>;
if(mp[mid]>x)r=mid-;else l=mid;
}return l;
}
int main(){
register int i;
n=read();m=read();tot=m<<;
for(i=;i<=m;i++)q[i].l=map[i]=read(),q[i].r=map[i+m]=read(),q[i].mn=read(),q[i].id=i;
sort(map+,map++tot);int tmp=;
for(i=;i<=tot;i++)if(map[i]!=map[i-])map[++tmp]=map[i];tot=tmp;tmp=;
for(i=;i<=tot;i++)if(map[i]+<map[i+])mp[++tmp]=map[i],mp[++tmp]=map[i]+;else mp[++tmp]=map[i];
tot=tmp;
for(i=;i<=m;i++)q[i].l=get(q[i].l),q[i].r=get(q[i].r);
sort(q+,q++m,cmp);
l=;r=m;
while(l<r){
mid=(l+r+)>>;
if(can(mid))l=mid;else r=mid-;
}
if(l==m)puts("");else printf("%d\n",l+);
return ;
}

UPD:妈呀之前有个地方大和小打反了>_<..已更正

UPD2: 还需要特判 值不够用的情况..因为数字互不相同&上限是10^9。

一个询问(L,R,A)意味着这个区间里有R-L+1个>=A的数...数据(可能出题人也)没有考虑到这部分..

正常版本见51nod1336。有个做法是二分图匹配,不过复杂度感人。

[bzoj1594] [Usaco2008 Jan]猜数游戏的更多相关文章

  1. [BZOJ1594] [Usaco2008 Jan]猜数游戏(二分 + 并查集)

    传送门 题中重要信息,每堆草的数量都不一样. 可以思考一下,什么情况下才会出现矛盾. 1.如果两个区间的最小值一样,但是这两个区间没有交集,那么就出现矛盾. 2.如果两个区间的最小值一样,并且这两个区 ...

  2. 【BZOJ1594】[Usaco2008 Jan]猜数游戏 二分答案+并查集

    [BZOJ1594][Usaco2008 Jan]猜数游戏 Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在 ...

  3. 【BZOJ 1594】 [Usaco2008 Jan]猜数游戏 (二分+并查集)

    1594: [Usaco2008 Jan]猜数游戏 Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在牛棚后面 ...

  4. BZOJ 1594 [Usaco2008 Jan]猜数游戏(线段数)

    1594: [Usaco2008 Jan]猜数游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 626  Solved: 260[Submit][S ...

  5. bzoj 1594: [Usaco2008 Jan]猜数游戏——二分+线段树

    Description 为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力. 游戏开始前,一头指定的奶牛会在牛棚后面摆N(1 <= N<= 1,000,00 ...

  6. BZOJ 1594: [Usaco2008 Jan]猜数游戏 线段树 + 思维 + 二分

    Code: #include<bits/stdc++.h> #define maxn 3000000 using namespace std; void setIO(string s) { ...

  7. bzoj 1594: [Usaco2008 Jan]猜数游戏【二分+线段树】

    写错一个符号多调一小时系列-- 二分答案,然后判断这个二分区间是否合法: 先按值从大到小排序,然后对于值相同的一些区间,如果没有交集则不合法:否则把并集在线段树上打上标记,然后值小于这个值的区间们,如 ...

  8. 【bzoj1594】猜数游戏

    1594: [Usaco2008 Jan]猜数游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 556  Solved: 225 Descripti ...

  9. usaco 猜数游戏

    Description 为了提高智商,锻炼思维能力,奶牛设计了一个猜数游戏.游戏开始前,贝西会在牛棚后面摆上N个数字.所有数字排成一条直线,按次序从1到N编号.每个数字在1到10^9之间,没有两个数字 ...

随机推荐

  1. CSS图片文字同行居中

    img{ display:inline-block; vertical-align:middle; }

  2. mac上虚拟机安装旧版本的macosx 10.8

    前言 由于测试的需要,需要10.8的macosx,但又不想降级自己mac版本,所以还是装虚拟机,Parallels Desktop试验了安装不了osx,就换VMware Fusion,发现是可以的. ...

  3. ASP.NET Cookie 概述

    什么是 Cookie? Cookie 是一小段文本信息,伴随着用户请求和页面在 Web 服务器和浏览器之间传递.Cookie 包含每次用户访问站点时 Web 应用程序都可以读取的信息. 例如,如果在用 ...

  4. 瞎j8封装第二版之数据库连接池

    写得很蛋疼,本来想支持多线程的,奈何对多线程和连接池理解着实太菜: 所以,起码是能拿到连接了... 但是还是不太懂这个连接池 我也是半抄别人的,以后再搞一搞这个吧. 先是配置文件 理想是很丰满的,奈何 ...

  5. SuperSocket 最基础入门

    ---恢复内容开始--- SuperSocket 是什么? 首先我们明确一下SuperSocket 本质是什么? 网络框架 !  ok , 那么我们直接上上官网,作者已经开源到Github,可以做两件 ...

  6. bzoj 4566: [Haoi2016]找相同字符

    Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两 个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别 ...

  7. iOS XIB等比例适配

    选择两个视图使其等宽高,再去约束里面就可以设置乘数因子. 简单的一个例子: 要求:设置白色视图的宽度为蓝色视图的一半 1.点击白色视图连线到父视图,选择 Equal Widths     2.选择右边 ...

  8. Golang fmt包使用小技巧

    h1 { margin-top: 0.6cm; margin-bottom: 0.58cm; direction: ltr; color: #000000; line-height: 200%; te ...

  9. python 爬去拉钩测试招聘信息

    代码如下: #coding:utf-8 import time import urllib.request from bs4 import BeautifulSoup file=open(r'meit ...

  10. 【分治】peak find

    分治算法 算法设计中一种常用的优化方法就是分治的思想,它的解决思路就是将原始的问题划分为性质一样,但是规模减小的子问题,然后通过子问题的解和合并子问题的解得到最终的解,就是分治的思想: 比较常见的分治 ...