花了一天时间颓废这道题(颓废才是重点。。。)
贪心的想,从左望右,对于可以放的位置,放在最后一定能得到最优解,反之亦然
那么先考虑处理掉所有0的区间,然后离散化。
然后处理出对于每个区间最少花多少代价处理出来。(前缀 ,后缀)
那么容易想到,如果离散化后只有k个点,那么直接输出答案即可。
并且 如果区间大小为1 也必须直接输出。
除此之外,所有输出的点一定是当前区间的右端点。
那么考虑不放在右端点此时的最优解一定是右端点的左边第一个点,
那么根据之前预处理出来的东西,可以判断出此时需要最少多少点,搞定
复杂度
O(mlogm)
O
(
m
log
m
)
c++`代码如下:
#define lowbit(x) (x&-x)
#define rep(i,x,y) for(register int i = x ; i <= y; ++ i)
#define repd(i,x,y) for(register int i = x ; i >= y; -- i)
using namespace std;
typedef long long ll;
template<typename T>inline void read(T&x)
{
char c;int sign = 1; x = 0;
do { c = getchar(); if(c == '-') sign = -1; }while(!isdigit(c));
do { x = x * 10 + c - '0'; c = getchar(); }while(isdigit(c));
x *= sign;
}
const int N = 1e5+50;
int n,m,k;
int t[N];
int w[N],z[N],s1[N],s2[N],cnt,tot,top;
struct DATA { int l,r; }a[N],b[N];
const bool cmp(DATA a,DATA b) { return a.l < b.l || a.l == b.l && a.r > b.r; }
int low[N],upp[N];
int main()
{
read(n); read(k); read(m);
rep(i,1,m)
{
int l,r,op;
read(l); read(r); read(op);
if(op == 1)
{
b[++ tot].l = l;
b[tot].r = r;
}
else t[l] -= 1,t[r + 1] += 1;
}
rep(i,1,n) t[i] += t[i - 1];
rep(i,1,n) if(! t[i] ) w[++cnt] = i;
if(k == cnt)
{
rep(i,1,cnt)
printf("%d\n",w[i]);
return 0;
}
w[cnt + 1] = n + 1;
rep(i,1,cnt + 1)
{
rep(j,w[i],w[i+1]-1)
low[j] = i;
rep(j,w[i-1]+1,w[i])
upp[j] = i;
}
rep(i,1,tot)
{
b[i].l = upp[b[i].l];
b[i].r = low[b[i].r];
if(b[i].l == b[i].r) z[b[i].l] = 1;
}
sort(b + 1 ,b + 1 + tot,cmp);
rep(i,1,tot)
{
if(a[top].l > a[top].r ) continue;
while(top && a[top].r >= b[i].r) -- top;
a[++top] = b[i];
}
int cur = 0;
m = top;
rep(i,1,m)
if(a[i].l <= cur) s1[i] = s1[i - 1];
else s1[i] = s1[i - 1] + 1,cur = a[i].r;
cur = n + 1;
repd(i,m,1)
if(a[i].r >= cur) s2[i] = s2[i + 1];
else s2[i] = s2[i + 1] + 1,cur = a[i].l;
rep(i,a[m].l+1,cnt) z[i] = cnt + 1;
repd(i,m,1)
rep(j,a[i-1].l + 1,a[i].l)
z[j] = i;
bool flag = 0;
rep(i,1,m)
{
if(s1[i] == s1[i - 1]) continue;
if(a[i].l == a[i].r)
{
flag = 1;
printf("%d\n", w[a[i].l ]);
continue;
}
if(s1[i - 1] + 1 + s2[z[a[i].r]]> k)
{
flag = 1;
printf("%d\n",w[a[i].r]);
}
}
if(!flag) puts("-1");
return 0;
}