2811: [Apio2012]Guard
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 936 Solved: 401
[ Submit][ Status][ Discuss]
Description
Input
Output
Sample Input
5 3 4
1 2 1
3 4 1
4 4 0
4 5 1
1 2 1
3 4 1
4 4 0
4 5 1
Sample Output
3
5
5
HINT
在这个样例中,有两种可能的安排方式:1,3,5 或者 2,3,5。即 3 和 5
后面必然躲着一个忍者。
考虑第一个灌木丛,存在一种安排方案使得它的后面躲着忍者,但也存在一
种安排方案使得它后面没有躲忍者,因此不应该输出 1。同理,不应该输出 2。
Source
#include<cstdio>
#include<vector>
#include<queue>
#include<ctime>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int INF = 2147483647;
const int maxn = 100010;
const int segn = 30 * maxn;
struct data{
int l,r;
}q[maxn];
struct node{
int x,id;
}stk[maxn];
vector<int> e[maxn];
int n,m,k,top,ans[maxn],ha[maxn],N;
int f[maxn],g[maxn],tot;
int fa[maxn],ed[maxn],Siz[maxn];
int exi[maxn];
inline LL getint()
{
LL ret = 0,f = 1;
char c = getchar();
while (c < '0' || c > '9')
{
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
ret = ret * 10 + c - '0',c = getchar();
return ret * f;
}
inline int find(int x)
{
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
inline bool cmp(data a,data b)
{
return a.l < b.l || (a.l == b.l && a.r > b.r);
}
inline int getr(int x,int i)
{
int l = i,r = tot;
while (r - l > 1)
{
int mid = l + r >> 1;
if (q[mid].l <= x) l = mid;
else r = mid;
}
if (q[r].l <= x) return r;
else return l;
}
inline int getl(int x,int i)
{
int l = 1,r = i;
while (r - l > 1)
{
int mid = l + r >> 1;
if (q[mid].r >= x) r = mid;
else l = mid;
}
if (q[l].r >= x) return l;
else return r;
}
int main()
{
#ifdef AMC
freopen("AMC1.txt","r",stdin);
// freopen("AMC2.txt","w",stdout);
#endif
n = getint(); k = getint(); m = getint();
for (int i = 1; i <= n; i++) fa[i] = i , ed[i] = i;
for (int i = 1; i <= m; i++)
{
int u = getint(),v = getint(),c = getint();
if (!c)
{
int p = ed[find(u - 1)] + 1;
while (p <= v)
{
int x = find(u - 1),y = find(p);
ed[x] = max(ed[y],ed[x]);
fa[y] = x; ed[y] = 0;
p = ed[x] + 1;
}
}
else q[++tot] = (data){u,v};
}
int now = ed[find(0)] + 1;
while (now <= n)
{
ha[++N] = now;
now = ed[find(now)] + 1;
}
if (N == k)
{
for (int i = 1; i <= N; i++)
printf("%d\n",ha[i]);
return 0;
}
for (int i = 1; i <= tot; i++)
{
q[i].l = lower_bound(ha + 1,ha + N + 1,q[i].l) - ha;
int t = lower_bound(ha + 1,ha + N + 1,q[i].r) - ha;
q[i].r = ha[t] == q[i].r ? t : t - 1;
}
sort(q + 1,q + tot + 1,cmp);
for (int i = 1; i <= tot; i++)
{
while (top && stk[top].x >= q[i].r)
exi[stk[top--].id] = 1;
stk[++top] = (node){q[i].r,i};
}
top = tot; tot = 0;
for (int i = 1; i <= top; i++)
{
if (exi[i]) continue;
q[++tot] = q[i];
}
f[1] = 1; int pos = q[1].r;
for (int i = 2; i <= tot; i++)
if (pos < q[i].l) pos = q[i].r , f[i] = f[i - 1] + 1;
else f[i] = f[i - 1];
g[tot] = 1; pos = q[tot].l;
for (int i = tot - 1; i >= 1; i--)
if (pos > q[i].r) pos = q[i].l , g[i] = g[i + 1] + 1;
else g[i] = g[i + 1];
int p = 0;
for (int i = 1; i <= tot; i++)
{
if (f[i - 1] + 1 != f[i]) continue;
if (q[i].l == q[i].r) {ans[++p] = q[i].r; continue;}
int l = getl(q[i].r - 1,i),r = getr(q[i].r - 1,i);
if (f[l - 1] + g[r + 1] + 1 > k) ans[++p] = q[i].r;
}
if (!p) printf("-1");
else for (int i = 1; i <= p; i++) printf("%d\n",ha[ans[i]]);
return 0;
}