[USACO 08JAN]Haybale Guessing

时间:2023-03-09 03:08:24
[USACO 08JAN]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.

给一段长度为n,每个位置上的数都不同的序列a[1..n]和q和问答,每个问答是(x, y, r)代表RMQ(a, x, y) = r, 要你给出最早的有矛盾的那个问答的编号。

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

题解

二分求解。

二分答案,将答案范围内的最小值$Ai$进行降序排序 然后我们可以观察一下得到的这些区间

对于不同$Ai$想一想如果它被之前出现的区间(比它大的$Ai$)都覆盖了,那么肯定就是有矛盾的

给点提示:对于同样的$Ai$询问要用交集,覆盖要用并集

这样就可以很明显地用线段树来搞了

 //It is made by Awson on 2017.10.27
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Lr(o) (o<<1)
#define Rr(o) (o<<1|1)
using namespace std;
const int N = ;
const int INF = ~0u>>; int n, q;
struct tt {
int l, r, a;
} a[N+], b[N+];
bool comp(const tt &a, const tt &b) {
if (a.a != b.a) return a.a > b.a;
return a.l == b.l ? a.r < b.r : a.l < b.l;
}
struct segment {
int sgm[(N<<)+], lazy[(N<<)+];
void build(int o, int l, int r) {
lazy[o] = ;
if (l == r) {
sgm[o] = INF; return;
}
int mid = (l+r)>>;
build(Lr(o), l, mid);
build(Rr(o), mid+, r);
sgm[o] = Max(sgm[Lr(o)], sgm[Rr(o)]);
}
void pushdown(int o) {
if (lazy[o]) {
sgm[Lr(o)] = sgm[Rr(o)] = lazy[Lr(o)] = lazy[Rr(o)] = lazy[o];
lazy[o] = ;
}
}
void update(int o, int l, int r, int a, int b, int key) {
if (a <= l && r <= b) {
sgm[o] = lazy[o] = key; return;
}
pushdown(o);
int mid = (l+r)>>;
if (a <= mid) update(Lr(o), l, mid, a, b, key);
if (mid < b) update(Rr(o), mid+, r, a, b, key);
sgm[o] = Max(sgm[Lr(o)], sgm[Rr(o)]);
}
int query(int o, int l, int r, int a, int b) {
if (a <= l && r <= b) return sgm[o];
pushdown(o);
int mid = (l+r)>>;
int a1 = , a2 = ;
if (a <= mid) a1 = query(Lr(o), l, mid, a, b);
if (mid < b) a2 = query(Rr(o), mid+, r, a, b);
return Max(a1, a2);
}
}T; bool get(int l, int r, int &x, int &y) {
int ll = b[l].l, rr = b[l].r;
for (int i = l+; i <= r; i++) {
int lll = b[i].l, rrr = b[i].r;
if (rr < lll) return false;
ll = lll;
}
x = ll, y = rr;
return true;
}
bool judge(int mid) {
T.build(, , n);
for (int i = ; i <= mid; i++) b[i] = a[i];
sort(b+, b++mid, comp);
for (int i = ; i <= mid; i++) {
int loc, l, r;
for (loc = i; loc <= mid; loc++) if (b[loc].a != b[i].a) break;
loc--;
if (!get(i, loc, l, r)) return false;
int t = T.query(, , n, l, r);
if (t != INF && t != b[i].a) return false;
for (int k = i; k <= loc; k++)
T.update(, , n, b[k].l, b[k].r, b[k].a);
i = loc;
}
return true;
}
void work() {
scanf("%d%d", &n, &q);
for (int i = ; i <= q; i++)
scanf("%d%d%d", &a[i].l, &a[i].r, &a[i].a);
int L = , R = q, ans = ;
while (L <= R) {
int mid = (L+R)>>;
if (judge(mid)) L = mid+;
else R = mid-, ans = mid;
}
printf("%d\n", ans);
}
int main() {
work();
return ;
}