hdu 4107 Gangster 线段数

做法:反正最终会形成的状况很多都是一整条一整条的区间中的所有值大于等于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;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值