【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

USACO 2008 January Gold

此题有多种解法。我的是二分答案+线段树区间覆盖

假设当增加了第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\n", 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\n");
    return 0;
}
时间: 2024-11-25 15:58:03

【POJ 3657】Haybale Guessing的相关文章

【POJ 1408】 Fishnet (叉积求面积)

[POJ 1408] Fishnet (叉积求面积) 一个1*1㎡的池塘 有2*n条线代表渔网 问这些网中围出来的最大面积 一个有效面积是相邻两行和相邻两列中间夹的四边形 Input为n 后面跟着四行 每行n个浮点数 每一行分别代表a,b,c,d 如图 并且保证a(i) > a(i-1) b(i) > b(i-1) c(i) > c(i-1) d(i) > d(i-1) n(n <= 30)*2+4(四个岸)条边 枚举点数就行 相邻的四个四个点枚举 找出围出的最大面积 找点用

【POJ 2513】Colored Sticks

[POJ 2513]Colored Sticks 并查集+字典树+欧拉通路 第一次做这么混的题..太混了-- 不过题不算难 字典树用来查字符串对应图中的点 每个单词做一个点(包括重复单词 题意就是每个边走且直走一次(欧拉通路 欧拉图的判定: 没有或者只有两个奇数度的点的图叫做欧拉图 有这些就可以解答此题了 另外需要注意题目范围是25W个木棍 所以最多可能有50W个点 卡了好多个RE 代码如下: #include <iostream> #include <cstdlib> #incl

2292: 【POJ Challenge 】永远挑战

2292: [POJ Challenge ]永远挑战 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 553  Solved: 230[Submit][Status][Discuss] Description lqp18_31和1tthinking经常出题来虐ftiasch.有一天, lqp18_31搞了一个有向图,每条边的长度都是1. 他想让ftiasch求出点1到点 N 的最短路."水题啊.", ftiasch这么说道. 所以1tth

【POJ 1201】 Intervals(差分约束系统)

[POJ 1201] Intervals(差分约束系统) 11 1716的升级版 把原本固定的边权改为不固定. Intervals Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23817   Accepted: 9023 Description You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. Write a p

【POJ 1228】Grandpa&#39;s Estate 凸包

找到凸包后暴力枚举边进行$check$,注意凸包是一条线(或者说两条线)的情况要输出$NO$ #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define N 1003 #define read(x) x = getint() using namespace std; inline int getint() { int k = 0, fh = 1; char c

【POJ 2750】 Potted Flower(线段树套dp)

[POJ 2750] Potted Flower(线段树套dp) Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4566   Accepted: 1739 Description The little cat takes over the management of a new park. There is a large circular statue in the center of the park, surrou

【POJ 2480】Longge&#39;s problem(欧拉函数)

题意 求$ \sum_{i=1}^n gcd(i,n) $ 给定 $n(1\le n\le 2^{32}) $. 链接 分析 用欧拉函数$φ(x)$求1到x-1有几个和x互质的数. gcd(i,n)必定是n的一个约数.若p是n的约数,那么gcd(i,n)==p的有$φ(n/p)$个数,因为要使gcd(i,n)==p,i/p和n/p必须是互质的.那么就是求i/p和n/p互质的i在[1,n]里有几个,就等价于,1/p,2/p,...,n/p里面有几个和n/p互质,即φ(n/p). 求和的话,约数为p

【POJ 3321】 Apple Tree (dfs重标号设区间+树状数组求和)

[POJ 3321] Apple Tree (dfs重标号设区间+树状数组求和) Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21966   Accepted: 6654 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. K

【POJ 1260】Pearls

[POJ 1260]Pearls dp问题 最近做背包做多了 一做动规就往背包想-- 这题其实也有点背包的意思(然而只是做背包做的看啥都像背包-- c件物品 有各自的数量a 和价值p 每进行一次交易的花费cost = (物品数+10)*价格 低价物品可以用高价一起购买 一次交易只能按照一种价值购买 初始dp[0] = 0 dp数组下标为物品件数 枚举物品种类 没枚举一种物品 遍历该物品之前物品量 假设之前有num件物品 当前枚举到的物品价值p 那么就要找到min(dp[k(0~num)] + (