zoukankan      html  css  js  c++  java
  • 线段树+ 区间更新

    题目链接: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.
    ");
                        continue;
                    }
                    else
                    {
                        printf("%d %d
    ",le-1,ri-1);
                    }
                }
                else if(t1==2)
                {
                    t3++;
                    temp=0;
                    update(t2,t3,1,n,1);
                    printf("%d
    ",temp);
                }
            }
            printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    hdu 2444 交叉染色判断二分图+二分最大匹配
    uva 交叉染色法10004
    poj 3177&&3352 求边双联通分量,先求桥,然后求分量( 临界表代码)
    poj 3177&&poj 3352加边构双联通(有重边)用tarjan 模板求的
    poj 3006水题打素数表
    POJ 3352 无向图边双连通分量,缩点,无重边
    hdu 1430 魔板 康托展开 + 很好的映射
    D. Artsem and Saunders 数学题
    vijos P1412多人背包 DP的前k优解
    1475 建设国家 DP
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10262832.html
Copyright © 2011-2022 走看看