Play With Sequence HDU - 3971

http://acm.hdu.edu.cn/showproblem.php?pid=3971

又学到了新姿势 居然还能每隔一段时间排个序...

通过维护区间最大最小值来剪枝 但肯定不够

如果一个数列是有序的 那这样维护区间最值 就相当于维护区间端点了 从而有logn得复杂度 所以可以每隔一定循环次数就把数列排序重新建树

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define N 0x3f3f3f3f3f3f3f3f

struct node
{
    ll minn;
    ll maxx;
    ll laz;
};

node tree[1000010];
ll num[250010];
int n,q;

void pushup(int cur)
{
    tree[cur].minn=min(tree[2*cur].minn,tree[2*cur+1].minn);
    tree[cur].maxx=max(tree[2*cur].maxx,tree[2*cur+1].maxx);
}

void pushdown(int cur)
{
    if(tree[cur].laz!=0)
    {
        tree[2*cur].minn+=tree[cur].laz;
        tree[2*cur].maxx+=tree[cur].laz;
        tree[2*cur].laz+=tree[cur].laz;
        tree[2*cur+1].minn+=tree[cur].laz;
        tree[2*cur+1].maxx+=tree[cur].laz;
        tree[2*cur+1].laz+=tree[cur].laz;
        tree[cur].laz=0;
    }
}

void build(int l,int r,int cur)
{
    int m;
    tree[cur].laz=0;
    if(l==r)
    {
        tree[cur].maxx=tree[cur].minn=num[l];
        return;
    }
    m=(l+r)/2;
    build(l,m,2*cur);
    build(m+1,r,2*cur+1);
    pushup(cur);
}

void update(ll pl,ll pr,ll val,int cur)
{
    if(pl<=tree[cur].minn&&tree[cur].maxx<=pr)
    {
        tree[cur].minn+=val;
        tree[cur].maxx+=val;
        tree[cur].laz+=val;
        return;
    }
    pushdown(cur);
    if(!(tree[2*cur].maxx<pl||tree[2*cur].minn>pr)) update(pl,pr,val,2*cur);
    if(!(tree[2*cur+1].maxx<pl||tree[2*cur+1].minn>pr)) update(pl,pr,val,2*cur+1);
    pushup(cur);
}

int query(ll pl,ll pr,int l,int r,int cur)
{
    int res,m;
    if(pl<=tree[cur].minn&&tree[cur].maxx<=pr)
    {
        return r-l+1;
    }
    pushdown(cur);
    res=0,m=(l+r)/2;
    if(!(tree[2*cur].maxx<pl||tree[2*cur].minn>pr)) res+=query(pl,pr,l,m,2*cur);
    if(!(tree[2*cur+1].maxx<pl||tree[2*cur+1].minn>pr)) res+=query(pl,pr,m+1,r,2*cur+1);
    return res;
}

void reset(int l,int r,int cur)
{
    int m;
    if(l==r)
    {
        num[l]=tree[cur].minn;
        return;
    }
    pushdown(cur);
    m=(l+r)/2;
    reset(l,m,2*cur);
    reset(m+1,r,2*cur+1);
}

int main()
{
    ll l,r,d;
    int i,j;
    char op[10];
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%lld",&num[i]);
        }
        sort(num+1,num+n+1);
        build(1,n,1);
        for(i=1;i<=q;i++)
        {
            scanf("%s",op);
            if(op[0]=='C')
            {
                scanf("%lld%lld%lld",&l,&r,&d);
                update(l,r,d,1);
            }
            else
            {
                scanf("%lld%lld",&l,&r);
                printf("%d\n",query(l,r,1,n,1));
            }
            if(i%4000==0)
            {
                reset(1,n,1);
                sort(num+1,num+n+1);
                build(1,n,1);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sunyutian1998/article/details/81177829