• Haybale Guessing 区间并查集


    Haybale Guessing

    Description

    The cows, who always have an inferiority complex about their intelligence, have a new guessing game to sharpen their brains.

    A designated 'Hay Cow' hides behind the barn and creates N (1 ≤ N ≤ 1,000,000) uniquely-sized stacks (conveniently numbered 1..N) of hay bales, each with 1..1,000,000,000 bales of hay.

    The other cows then ask the Hay Cow a series of Q (1 ≤ Q ≤ 25,000) questions about the the stacks, all having the same form:

    What is the smallest number of bales of any stack in the range of stack numbers Ql..Qh (1 ≤ Ql ≤ N; Ql ≤ Qh ≤ N)?
    The Hay Cow answers each of these queries with a single integer A whose truthfulness is not guaranteed.

    Help the other cows determine if the answers given by the Hay Cow are self-consistent or if certain answers contradict others.

    Input

    • 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: Ql, Qh, and A

    Output

    • 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.

    Sample Input

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

    Sample Output

    3
    

    题意:有一个没有重复数字的序列,给定多个条件:区间[x,y]的最小值,输出最早出现矛盾的条件编号。
    这题用线段树也能做,不过代码太长了。
    由于是没有重复的数字,所以判断是否有矛盾:

    1. 两个区间最小值相同,则一定有交集,否则就有矛盾。
    2. 两个区间A,B最小值不相同,如果A是B的子集,那么(A_{min}geq B_{min}),否则也有矛盾。

    这样,可以通过二分求得答案。
    注意,排序之后,两个区间最小值相同,则区间并集最小值都相同,用来覆盖,区间交集用来查询是否符合之前的条件。

    #include<bits/stdc++.h>
    using namespace std;
    #define Init(arr,val) memset(arr,val,sizeof(arr))
    const int inf=0x3f3f3f3f,mod=1e9+7,MAXN=1e6+8;
    typedef long long ll;
    struct Node {
        int x,y,val;
        bool operator<(const Node&o)const {
            return val>o.val;
        }
    } d[25005],t[25005];
    int n,q;
    int fa[MAXN];
    inline int find(int x) {
        while(x!=fa[x])
            x=fa[x]=fa[fa[x]];
        return x;
    }
    bool check(int mid) {
        for(int i=0; i<=n+1; ++i)fa[i]=i;
        for(int i=0;i<mid;++i)t[i]=d[i];
        sort(t,t+mid);
        int lmin,lmax,rmin,rmax;
        lmin=lmax=t[0].x;
        rmin=rmax=t[0].y;
        for(int i=1; i<mid; ++i) {
            if(t[i].val==t[i-1].val) {
            //两个区间最小值一样,判断是否有交集
            //可能有3个以上的区间满足,所以要用四个变量记录。
                lmin=min(lmin,t[i].x);
                lmax=max(lmax,t[i].x);
                rmin=min(rmin,t[i].y);
                rmax=max(rmax,t[i].y);
                if(lmax>rmin)return 1;//区间不相交。
            } else {
                if(find(lmax)>rmin)return 1;//
                for(int j=lmin; j<=rmax; ++j) {
                    j=find(j);
                    fa[j]=find(rmax+1);//不+1的话还要多个判断是否区间只有一个点。
                }
                lmin=lmax=t[i].x;
                rmin=rmax=t[i].y;
            }
        }
        if(find(lmax)>rmin)return 1;//可能没有更新
        return 0;
    }
    int main() {
        std::ios::sync_with_stdio(0);
        std::cin.tie(0);
        cin>>n>>q;
        for(int i=0; i<q; ++i)
            cin>>d[i].x>>d[i].y>>d[i].val;
        int l=1,r=q,ans=0;
        while(l<=r) {
            int mid=(r+l)>>1;
            if(check(mid)) {
                r=mid-1;
                ans=mid;
            } else l=mid+1;
        }
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    表单标签
    无序列表有序列表
    跳转锚点
    HTML标签01
    HTML基本结构和属性
    python爬虫学习笔记(二十三)-Scrapy框架 CrawlSpider
    python爬虫学习笔记(二十二)-Scrapy框架 案例实现
    python爬虫学习笔记(二十一)-Scrapy框架 setting
    python爬虫学习笔记(二十)-Scrapy框架 Pipeline
    python爬虫学习笔记(十九)-Scrapy 数据的保存
  • 原文地址:https://www.cnblogs.com/foursmonth/p/14145148.html
Copyright © 2020-2023  润新知