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 ≤ 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
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\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; }