二分哪一次操作是最后一次正确的操作 ,+1即为错误操作。
把最小值相同的询问确定下来,可以得到一个最小的集合,再更新这个集合的所属,若有冲突就说明此操作有问题。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXD 1000010
#define MAXQ 25010
using namespace std;
int N, Q, X, p[MAXD], col[MAXD], s[MAXD];
struct Que
{
int x, y, z;
bool operator < (const Que &t) const
{
return z > t.z;
}
}q[MAXQ], t[MAXQ];
int getfa(int x)
{
if(p[x] == x)
return x;
else
return p[x]=getfa(p[x]);
}
void init()
{
int i;
for(i = 1; i <= Q; i ++)
scanf("%d%d%d", &q[i].x, &q[i].y, &q[i].z);
}
void refresh(int x, int y)
{
int i = getfa(x - 1), j = getfa(x);
col[j] = 1;
for(i = j; i <= y; i = j)
{
j = getfa(i + 1);
if(col[j] || j <= y)
col[j] = 1, p[i] = j;
}
}
int deal(int n)
{
int i, j, x, y, tx, ty, fa;
for(i = 0; i <= N + 1; i ++)
p[i] = i, col[i] = 0;
for(i = 1; i <= n; i ++)
t[i] = q[i];
sort(t + 1, t + 1 + n);
for(i = 1; i <= n; i = j + 1)
{
x = tx = t[i].x;
y = ty = t[i].y;
for(j = i; j < n && t[j + 1].z == t[j].z;)
{
++ j;
x = max(x, t[j].x);
y = min(y, t[j].y);
tx = min(tx, t[j].x);
ty = max(ty, t[j].y);
}
if(x > y)
return 0;
fa = getfa(x);
if(col[fa] != 0 && getfa(fa) >= y)
return 0;
refresh(tx, ty);
}
return 1;
}
void solve()
{
int mid, ll, rr;
ll = 1;
rr = Q + 1;
for(;;)
{
mid = (ll + rr) >> 1;
if(mid == ll)
break;
if(deal(mid))
ll = mid;
else
rr = mid;
}
printf("%d\n", mid == Q ? 0 : mid + 1);
}
int main()
{
scanf("%d%d", &N, &Q);
init();
solve();
return 0;
}