zoukankan      html  css  js  c++  java
  • 洛谷 P2898 [USACO08JAN]haybale猜测Haybale Guessing 解题报告

    [USACO08JAN]haybale猜测Haybale Guessing

    题目描述

    给一段长度为(n),每个位置上的数都不同的序列(a[1dots 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.


    牛客居然考原题...不过题目还是很棒的。

    考虑什么情况会产生矛盾。

    1. 两段不相交的区间的最小值相同

    2. 一个最小值大的区间完全覆盖了一个最小值小的区间

    3. 一个区间被其他几个区间完全填充时的,最小值比它们都小。

    直接处理很难,如果我们可以按顺序处理的话,比如按最小值从大到小排序,无疑会方便很多,但是回答本身就是带顺序的,我们不可以直接打乱它们。

    怎么办呢,二分答案。这无疑是一个很棒的二分答案的思路。正确性很显然。

    考虑判断前(i)个区间是否产生矛盾,我们按最小值从大到小排序,然后一个一个加入。

    1. 如果当前区间被其他区间完全覆盖,返回不合法。
    2. 如果当前区间与其他区间最小值相同
      • 如果两个区间不交,返回不合法
      • 如果两个区间有交,检查它们的交集是否被别人覆盖,拿它们的并集去覆盖别人。

    检查区间覆盖可以通过线段树染色求得,只需要区间赋值(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
    ",l);
        return 0;
    }
    

    2018.10.29

  • 相关阅读:
    Ubuntu16.04 + OpenCV源码 + Qt5.10 安装、配置
    DML和DQL
    初识MySql
    表单校验
    使用jQuery操作DOM
    jQuery中的事件与动画
    jQuery选择器
    初识jQuery
    JavaScript对象及初识OOP
    JavaScript操作DOM对象
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9873015.html
Copyright © 2011-2022 走看看