做法:反正最终会形成的状况很多都是一整条一整条的区间中的所有值大于等于limit.所以一开始可以不用懒惰更新,直接更新至一段最小值大于lim或者最大值小于lim的区间。
题目时间卡的很紧,手动输入还有优化一下update函数,多参数的函数效率果然低到加,最后险过。
#include<cstdio>
#include<cstring>
#define left l,m,x<<1
#define right m+1,r,x<<1|1
const int LMT=200005;
int p,minu[LMT<<2],maxu[LMT<<2],cov[LMT<<2];
struct no
{
int l,r;
}node[LMT<<2];
inline int get()
{
int res=0;
char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9')
{
res*=10;
res+=c-'0';
c=getchar();
}
return res;
}
void build(int l,int r,int x)
{
minu[x]=maxu[x]=cov[x]=0;
node[x].l=l;node[x].r=r;
if(l==r)return;
int m=(l+r)>>1;
build(left);build(right);
}
void cut(int x)
{
if(cov[x])
{
minu[x<<1]+=cov[x];
maxu[x<<1]+=cov[x];
cov[x<<1]+=cov[x];
minu[x<<1|1]+=cov[x];
maxu[x<<1|1]+=cov[x];
cov[x<<1|1]+=cov[x];
cov[x]=0;
}
}
void update(int op,int L,int R,int x)
{
if(L<=node[x].l&&node[x].r<=R)
{
if(minu[x]>=p)
{
minu[x]+=op<<1;
maxu[x]+=op<<1;
cov[x]+=op<<1;
return;
}
if(maxu[x]<p)
{
minu[x]+=op;
maxu[x]+=op;
cov[x]+=op;
return;
}
}
cut(x);
int m=(node[x].r+node[x].l)>>1;
if(L<=m)update(op,L,R,x<<1);
if(R>m)update(op,L,R,x<<1|1);
minu[x]=minu[x<<1]<minu[x<<1|1]?minu[x<<1]:minu[x<<1|1];
maxu[x]=maxu[x<<1]>maxu[x<<1|1]?maxu[x<<1]:maxu[x<<1|1];
}
void query(int x)
{
if(node[x].l==node[x].r)
{
if(node[x].l>1)printf(" ");
printf("%d",minu[x]);
return ;
}
cut(x);
int m=(node[x].l+node[x].r)>>1;
query(x<<1);
query(x<<1|1);
}
int main()
{
int n,m,c,l,r;
while(~scanf("%d%d%d",&n,&m,&p))
{
build(1,n,1);
while(m--)
{
l=get();r=get();c=get();
update(c,l,r,1);
}
query(1);
printf("\n");
}
return 0;
}