hdu 3577 线段树,成段更新

这个题有一点要考虑到,就是某人从a站坐到b站,他在b站就下车了,他在车上乘坐的区间为a到b-1。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN=1000005;
struct node
{
    int l,r;
    int sum;
    int lazy;
    int mid()
    {
        return (l+r)>>1;
    }
};
node tree[MAXN*4];
int res[100005];
inline void pushup(int pos)
{
    tree[pos].sum=max(tree[pos<<1].sum,tree[pos<<1|1].sum);
}
inline void pushdown(int pos)
{
    if(tree[pos].lazy)
    {
        tree[pos<<1].sum+=tree[pos].lazy;
        tree[pos<<1|1].sum+=tree[pos].lazy;
        tree[pos<<1].lazy+=tree[pos].lazy;
        tree[pos<<1|1].lazy+=tree[pos].lazy;
        tree[pos].lazy=0;
    }
}
void build(int l,int r,int pos)
{
    tree[pos].l=l;
    tree[pos].r=r;
    if(l==r)
    {
        tree[pos].sum=0;
        tree[pos].lazy=0;
        return ;
    }
    int mid=tree[pos].mid();
    build(l,mid,pos<<1);
    build(mid+1,r,pos<<1|1);
    pushup(pos);
    tree[pos].lazy=0;
}
void update(int l,int r,int pos)
{
    if(l==tree[pos].l&&r==tree[pos].r)
    {
        tree[pos].sum+=1;
        tree[pos].lazy+=1;
        return ;
    }
    pushdown(pos);
    int mid=tree[pos].mid();
    if(r<=mid)
        update(l,r,pos<<1);
    else if(l>mid)
        update(l,r,pos<<1|1);
    else
    {
        update(l,mid,pos<<1);
        update(mid+1,r,pos<<1|1);
    }
    pushup(pos);
}
int query(int l,int r,int pos)
{
    if(l==tree[pos].l&&r==tree[pos].r)
    {
        return tree[pos].sum;
    }
    pushdown(pos);
    int mid=tree[pos].mid();
    if(r<=mid)
        return query(l,r,pos<<1);
    else if(l>mid)
        return query(l,r,pos<<1|1);
    else
        return max(query(l,mid,pos<<1),query(mid+1,r,pos<<1|1));
}
int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
        int k,q;
        cas++;
        scanf("%d%d",&k,&q);
        int i;
        build(1,1000000,1);
        int kk=0;
        for(i=1;i<=q;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            b--;
            if(query(a,b,1)<k)
            {
                res[kk++]=i;
                update(a,b,1);
            }
        }
        printf("Case %d:\n",cas);
        for(i=0;i<kk;i++)
            printf("%d ",res[i]);
        printf("\n\n");
    }
    return 0;
}


你可能感兴趣的:(hdu 3577 线段树,成段更新)