线段树+ 区间更新

题目链接:https://cn.vjudge.net/problem/HDU-4614

又是一个改了两天的代码。。。。原来数组开小了也会报超时。

具体思路:按照区间更新的思路打就可以了,不过有很多可以优化的地方,具体见代码。

AC代码:

#include<iostream>
#include<string>
#include<cstring>
#include<iomanip>
#include<cmath>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<stdio.h>
#include<algorithm>
#include<set>
using namespace std;
# define inf 0x3f3f3f3f
# define maxn 1000001
# define ll long long
# define lson l,m,rt<<1
# define rson m+1,r,rt<<1|1
int a[maxn*10];
int col[maxn*10];
int flag;
int le,ri;
int t1,t2,t3;
int temp;
int k;
void up(int rt)
{
    a[rt]=a[rt<<1]+a[rt<<1|1];
}
void down(int rt,int l,int r)
{
    if(col[rt]!=-1)
    {
        col[rt<<1]=col[rt<<1|1]=col[rt];
        int mid=(r+l)/2;
        a[rt<<1]=(mid-l+1)*col[rt];//注意,a数组存的是这个节点往下有多少多话,所以复制的时候需要注意区间长度。
        a[rt<<1|1]=(r-mid)*col[rt];
        //a[rt<<1]=a[rt<<1|1]=a[rt];
        col[rt]=-1;
    }
}
void buildtree(int l,int r,int rt)
{
    a[rt]=0;
    col[rt]=-1;
    if(l==r)return ;
    int m=(l+r)>>1;
    buildtree(lson);
    buildtree(rson);
}
void update(int L,int R,int l,int r,int rt)
{
    if(t3<=0)return ;
    if(L<=l&&R>=r)
    {

        if(t1==1)//如果是插花
        {if(r-l+1==a[rt])return ;//如果这个区间已经插满了,返回,优化
            if(a[rt]==0&&t3>=(r-l+1))//当前的区间都能插花再更新
            {
                col[rt]=1;
                flag=1;
                a[rt]=r-l+1;
                le=min(l,le);
                ri=max(r,ri);
                t3-=(r-l+1);
                return ;
            }
        }
        else if(t1==2)
        {
            temp+=a[rt];//先把原来的和求好了,这样就能省一个查询的过程。
            a[rt]=0;
            col[rt]=0;
            return ;
        }
       // if(l==r)return ;
    }
    down(rt,l,r);
    int m=(l+r)>>1;
    if(L<=m)update(L,R,lson);
    if(R>m)update(L,R,rson);
    up(rt);
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        buildtree(1,n,1);//初始化
        while(m--)
        {
            flag=0;
            le=inf,ri=0;
            scanf("%d%d%d",&t1,&t2,&t3);
            t2++;
            if(t1==1)
            {
                update(t2,n,1,n,1);
                if(flag==0)
                {
                    printf("Can not put any one.\n");
                    continue;
                }
                else
                {
                    printf("%d %d\n",le-1,ri-1);
                }
            }
            else if(t1==2)
            {
                t3++;
                temp=0;
                update(t2,t3,1,n,1);
                printf("%d\n",temp);
            }
        }
        printf("\n");
    }
    return 0;
}

 

posted @ 2018-11-08 22:09  Let_Life_Stop  阅读(287)  评论(0编辑  收藏  举报