• 【POJ 3657】Haybale Guessing


    Haybale Guessing
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 2093   Accepted: 567

    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 ≤ NQl ≤ 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: QlQh, 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
    

    Source

     
    此题有多种解法。我的是二分答案+线段树区间覆盖
    假设当增加了第K句回答的时候会起冲突,求K的最小值,也就是说我们可以二分这个K。如果从1~第K句话会起冲突,那么我们可以看一下K前面会不会已经起了冲突了呢?如果第K句话并不会起冲突,那答案肯定就在K后面了。
    然后我们如何检查是否已经起冲突呢?
    很明显,大的A值会影响小的A值,为什么?假设A1<A2,那么很明显当A1先覆盖了,A2再覆盖的时候我们肯定会不好处理了,因为有很多种情况。
    所以,我们可以用A2先覆盖,然后和A1区间的交集是不能覆盖的。(想想为什么)
    我们可以从A值的大到小进行覆盖(即染色),查询一下,当前要覆盖的A值的区间是否已经全部被染色了,如果是,那么说明已经起了冲突。
    时间复杂度有点大,是O(log2Q * Qlog2N),好像比USACO的官方解法要慢,反正我也看不懂。
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 1000005;
    const int MAXQ = 25005;
    
    struct Discret
    {
        int a;
        int ID;
    
        bool operator < (const Discret &b) const
        {
            return a < b.a;
        }
    }A[MAXQ];
    
    int ql[MAXQ], qr[MAXQ];
    int orig[MAXQ];
    int leftv[2][MAXQ], rightv[2][MAXQ];
    bool v[MAXN << 2];
    int n, q;
    int note;
    int y1, y2;
    bool flag;
    
    void pushdown(int o)
    {
        if (v[o])
        {
            int lc = o << 1, rc = lc + 1;
            v[lc] = v[rc] = v[o];
        }
    }
    
    void update(int o, int L, int R)
    {
        if (y1 <= L && R <= y2) v[o] = true;
        else
        {
            pushdown(o);
            int mid = (L + R) >> 1;
            int lc = o << 1;
            int rc = lc + 1;
            if (mid >= y1) update(lc, L, mid);
            if (mid + 1 <= y2) update(rc, mid + 1, R);
            v[o] = v[lc] && v[rc];
        }
    }
    
    void query(int o, int L, int R)
    {
        if (y1 <= L && R <= y2)
        {
            flag = flag && v[o];
            return;
        }
        pushdown(o);
        int mid = (L + R) >> 1;
        int lc = o << 1, rc = lc + 1;
        if (mid >= y1) query(lc, L, mid);
        if (mid + 1 <= y2) query(rc, mid + 1, R);
    }
    
    bool check(int qest)
    {
        memset(v, false, sizeof(v));
        memset(leftv, 0x7f, sizeof(leftv));
        memset(rightv, 0, sizeof(rightv));
        for (int i = 1; i <= qest; ++i)
        {
            if (leftv[0][orig[i]] <= rightv[0][orig[i]])
            {
                leftv[0][orig[i]] = max(leftv[0][orig[i]], ql[i]);
                leftv[1][orig[i]] = min(leftv[1][orig[i]], ql[i]);
                rightv[0][orig[i]] = min(rightv[0][orig[i]], qr[i]);
                rightv[1][orig[i]] = max(rightv[1][orig[i]], qr[i]);
                if (leftv[0][orig[i]] > rightv[0][orig[i]]) return true;
            }
            else
            {
                leftv[0][orig[i]] = leftv[1][orig[i]] = ql[i];
                rightv[0][orig[i]] = rightv[1][orig[i]] = qr[i];
            }
        }
        for (int i = note; i >= 0; --i)
        {
            y1 = leftv[0][i];
            y2 = rightv[0][i];
            if (y1 <= y2)
            {
                flag = true;
                query(1, 1, n);
                if (flag) return true;
                y1 = leftv[1][i];
                y2 = rightv[1][i];
                update(1, 1, n);
            }
        }
        return false;
    }
    
    void binarySearch(int l, int r)
    {
        if (l == r)
        {
            printf("%d
    ", l);
            return;
        }
        int mid = (l + r) >> 1;
        if (check(mid)) binarySearch(l, mid);
        else binarySearch(mid + 1, r);
    }
    
    int main()
    {
        scanf("%d %d", &n, &q);
        for (int i = 1; i <= q; ++i) scanf("%d %d %d", &ql[i], &qr[i], &A[i].a), A[i].ID = i;
        sort(A + 1, A + q + 1);
        note = -1;
        int tmp = -1;
        for (int i = 1; i <= q; ++i)
            if (tmp < A[i].a) orig[A[i].ID] = ++note, tmp = A[i].a;
            else orig[A[i].ID] = note;
        if (check(q))
            binarySearch(1, q);
        else printf("0
    ");
        return 0;
    }
  • 相关阅读:
    杂记
    asp.net preview 5 bug[转]
    jquery笔记
    北京互联网创业团队诚邀英才加盟
    伊瓜苏大瀑布
    log4net udp组件的应用
    Mock介绍
    自写的BackgroundWorker的学习例子
    RegexBuddy使用例子,及Visual Studio中正则使用的请教
    TestDriven.NET2.14.2190(not RTM) last update at 2008723
  • 原文地址:https://www.cnblogs.com/albert7xie/p/4781641.html
Copyright © 2020-2023  润新知