zoukankan      html  css  js  c++  java
  • 【BZOJ1594】[Usaco2008 Jan]猜数游戏 二分答案+并查集

    【BZOJ1594】[Usaco2008 Jan]猜数游戏

    Description

    为了提高自己低得可怜的智商,奶牛们设计了一个新的猜数游戏,来锻炼她们的逻辑推理能力。 游戏开始前,一头指定的奶牛会在牛棚后面摆N(1 <= N<= 1,000,000)堆干草,每堆有若干捆,并且没有哪两堆中的草一样多。所有草堆排成一条直线,从左到右依次按1..N编号,每堆中草的捆数在1..1,000,000,000之间。 然后,游戏开始。另一头参与游戏的奶牛会问那头摆干草的奶牛 Q(1 <= Q <= 25,000)个问题,问题的格式如下: 编号为Ql..Qh(1 <= Ql <= Qh <= N)的草堆中,最小的那堆里有多少捆草? 对于每个问题,摆干草的奶牛回答一个数字A,但或许是不想让提问的奶牛那么容易地得到答案,又或许是她自己可能记错每堆中干草的捆数,总之,她的回答不保证是正确的。 请你帮助提问的奶牛判断一下,摆干草的奶牛的回答是否有自相矛盾之处。

    Input

    * 第1行: 2个用空格隔开的整数:N 和 Q

    * 第2..Q+1行: 每行为3个用空格隔开的整数Ql、Qh、A,描述了一个问题以及它 对应的回答

    Output

    * 第1行: 如果摆干草的奶牛有可能完全正确地回答了这些问题(也就是说,能 找到一种使得所有回答都合理的摆放干草的方法),输出0,否则输出 1个1..Q中的数,表示这个问题的答案与它之前的那些回答有冲突之处

    Sample Input

    20 4
    1 10 7
    5 19 7
    3 12 8
    11 15 12

    输入说明:

    编号为1..10的草堆中,最小的那堆里有7捆草,编号为5..19的草堆中同样
    如此;编号为3..12的草堆中最小的堆里是8捆草,11..15堆中的最小的堆里是12
    捆。

    Sample Output

    3

    输出说明:

    对于第3个问题“3 12”的回答“8”与前面两个回答冲突。因为每堆中草的
    捆数唯一,从前两个回答中我们能推断出,编号为5..10的干草堆中最小的那堆
    里有7捆干草。很显然,第3个问题的回答与这个推断冲突。

    HINT

    注意:如果有冲突出现输出一个数m,使得前M-1个命题不冲突。

    题解:先二分答案,然后将前mid个询问按照A从大到小排序,然后判断:如果几个A比较大的区间的并集包含了一些A比较小的区间的交集,那么一定出现矛盾

    区间的包含关系我们可以用一个线段树来维护,当然,另一种神奇的做法就是用并查集

    如果我们要覆盖[l,r]这段区间,那么我们就暴力令[l,r]中所有元素的fa都指向r+1,(可以证明均摊的复杂度很小),然后判断某个区间[ll,rr]是否被覆盖过是就看find(ll)是否大于rr就行了

    注意所有干草堆的大小都不相同

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int n,m;
    int f[1000010];
    struct QUERY
    {
        int qa,qb,qv;
    }q[25010],p[25010];
    int find(int x)
    {
        return (f[x]==x)?x:(f[x]=find(f[x]));
    }
    bool cmp(QUERY a,QUERY b)
    {
        return a.qv>b.qv;
    }
    bool solve(int sta)
    {
        int i,j,l1,l2,r1,r2;
        for(i=1;i<=n+1;i++)    f[i]=i;
        for(i=1;i<=sta;i++)    q[i].qa=p[i].qa,q[i].qb=p[i].qb,q[i].qv=p[i].qv;
        sort(q+1,q+sta+1,cmp);
        l1=l2=q[1].qa,r1=r2=q[1].qb;
        for(i=2;i<=sta;i++)
        {
            if(q[i].qv<q[i-1].qv)
            {
                if(find(l1)>r1)    return false;
                for(j=f[l2];j<=r2;j=f[j])
                {
                    find(j);
                    f[j]=find(j+1);
                }
                l1=l2=q[i].qa,r1=r2=q[i].qb;
            }
            else
            {
                l1=max(l1,q[i].qa),l2=min(l2,q[i].qa),r1=min(r1,q[i].qb),r2=max(r2,q[i].qb);
                if(r1<l1)    return false;
            }
        }
        if(find(l1)>r1)    return false;
        return true;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)    scanf("%d%d%d",&p[i].qa,&p[i].qb,&p[i].qv);
        int l=1,r=m+1,mid;
        while(l<r)
        {
            mid=l+r>>1;
            if(solve(mid))    l=mid+1;
            else    r=mid;
        }
        printf("%d",l>n?0:l);
        return 0;
    }
  • 相关阅读:
    一、CentOS 7安装部署GitLab服务器

    四、指定Nginx启动用户
    三、Nginx支持php
    二、Nginx多站点配置(参考宝塔的)分析
    一、Nginx多站点配置
    一、PHP和Apache实现多用户自助建站
    Flask+uwsgi+Nginx+Ubuntu部署
    flask 上传头像
    flask 分页
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6405758.html
Copyright © 2011-2022 走看看