线段树合集

poj3667

hdu2871

hdu4614 

poj1631 线段树求LIS  单点





poj3667

#include<stdio.h>
#include<iostream>
using namespace std;
#define maxn 111111
int mmax[maxn<<2],lmax[maxn<<2],rmax[maxn<<2];
int set[maxn<<2];
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define mid ((l+r)>>1)
void pushup(int rt,int l,int r)
{
    
        lmax[rt]=lmax[ls];
        rmax[rt]=rmax[rs];
         if(lmax[ls]==(mid-l+1))lmax[rt]+=lmax[rs];
           if(rmax[rs]==(r-mid))rmax[rt]+=rmax[ls];
        mmax[rt]=max(mmax[ls],mmax[rs]);
        mmax[rt]=max(lmax[rs]+rmax[ls],mmax[rt]);
}
void pushdown(int rt,int l,int r)
{
    if(set[rt]!=-1)
    {
        set[ls]=set[rs]=set[rt];
        set[rt]=-1;
        lmax[ls]=mmax[ls]=rmax[ls]=(set[ls]?0:(mid-l+1));
        lmax[rs]=mmax[rs]=rmax[rs]=(set[rs]?0:(r-mid));
        
    }
}
void build(int rt,int l,int r)
{
    set[rt]=-1;
    mmax[rt]=lmax[rt]=rmax[rt]=(r-l+1);
    if(l==r)return ;
    build(ls,l,mid);
    build(rs,mid+1,r);
}
void ins(int rt,int l,int r,int L,int R,int w)
{
    if(L<=l&&r<=R)
    {
        mmax[rt]=lmax[rt]=rmax[rt]=w?0:(r-l+1);
        set[rt]=w;
        return ;
    }
    pushdown(rt,l,r);
    if(L<=mid)ins(ls,l,mid,L,R,w);
    if(mid<R)ins(rs,mid+1,r,L,R,w);
    pushup(rt,l,r);
}
int query(int rt,int l,int r,int w)
{
    if(l==r)return l;
    pushdown(rt,l,r);
    if(mmax[ls]>=w) return query(ls,l,mid,w);
    if((rmax[ls]+lmax[rs])>=w) return (mid-rmax[ls]+1);
    return query(rs,mid+1,r,w);
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    
        int op,a,b;
        build(1,1,n);
        
        while(m--)
        {
            scanf("%d",&op);
            if(op==1){
                scanf("%d",&a);
                if(mmax[1]<a)printf("0\n");
                else
                 {
                      int _x=query(1,1,n,a);
                        printf("%d\n",_x);
                           ins(1,1,n,_x,_x+a-1,1);
                 }
            }
            else{
                 scanf("%d%d",&a,&b);
                  ins(1,1,n,a,a+b-1,0);
            }
        }
    return 0;
}

hdu 2871

hotel加强版

删除操作要通过全段的update来进行

#include<stdio.h>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define mid ((l+r)>>1)
#define maxn 110000
int mmax[maxn<<2],lmax[maxn<<2],rmax[maxn<<2];
int lazy[maxn<<2];
struct block{
    int begin,end;
};
vector<block>g;
void pushdown(int rt,int l,int r)
{
    if(lazy[rt]!=-1)
    {
        lazy[ls]=lazy[rs]=lazy[rt];
        lazy[rt]=-1;
        mmax[ls]=lmax[ls]=rmax[ls]=lazy[ls]?0:(mid-l+1);
        mmax[rs]=lmax[rs]=rmax[rs]=lazy[rs]?0:(r-mid);
    }
}
void pushup(int rt,int l,int r)
{
    
    lmax[rt]=lmax[ls];
    rmax[rt]=rmax[rs];
    if(lmax[ls]==(mid-l+1))lmax[rt]+=lmax[rs];
    if(rmax[rs]==(r-mid))rmax[rt]+=rmax[ls];
    mmax[rt]=max(mmax[ls],mmax[rs]);
    mmax[rt]=max(mmax[rt],rmax[ls]+lmax[rs]);
}
void reset(int rt,int l,int r)
{
    lazy[rt]=-1;
    mmax[rt]=lmax[rt]=rmax[rt]=(r-l+1);
    
    if(l==r)return ;
    reset(ls,l,mid);
    reset(rs,mid+1,r);
}
void update(int rt,int l,int r,int L,int R,int w)
{
    if(L<=l&&r<=R){
        mmax[rt]=rmax[rt]=lmax[rt]=w?0:(r-l+1);
        lazy[rt]=w;
        return ;
    }
    pushdown(rt,l,r);
    if(L<=mid)update(ls,l,mid,L,R,w);
    if(mid<R)update(rs,mid+1,r,L,R,w);
    pushup(rt,l,r);
}
int query(int rt,int l,int r,int L,int R,int w)
{
    if(l==r)return l;
    
    pushdown(rt,l,r);
    if(mmax[ls]>=w)return query(ls,l,mid,L,R,w);
    else if((rmax[ls]+lmax[rs])>=w)
        return mid-rmax[ls]+1;
    else return query(rs,mid+1,r,L,R,w);
}
bool cmp(block a,block b){return a.begin<b.begin;}
int main()
{
    //    puts("");
    int n,m,x;
    char op[10];
    while(~scanf("%d%d",&n,&m))
    {
        g.clear();
        
        reset(1,1,n);
        for(int i=0;i<m;++i)
        {
            scanf("%s",op);
            if(op[0]=='R')
            {
                printf("Reset Now\n");
                g.clear();
                update(1,1,n,1,n,0);
            }
            else
            {
                scanf("%d",&x);
                
                if(op[0]=='N')
                {
                    
                    if(mmax[1]<x)printf("Reject New\n");
                    else
                    {
                        int ans=query(1,1,n,1,n,x);
                        printf("New at %d\n",ans);
                        block s;
                        s.begin=ans;
                        s.end=ans+x-1;
                        update(1,1,n,ans,ans+x-1,1);
                        vector<block>::iterator it=upper_bound(g.begin(),g.end(),s,cmp);
                        g.insert(it,s);
                        //不能sort vector
                    }
                }
                else if(op[0]=='G')
                {
                    if(x>g.size())
                        printf("Reject Get\n");
                    else
                        printf("Get at %d\n",g[x-1].begin);
                }
                else if(op[0]=='F')
                {
                    block z;
                    z.begin=x;
                    z.end=x;
                    vector<block>::iterator it=upper_bound(g.begin(), g.end(),z,cmp);
                    int tmp=(int)(it-g.begin()-1);
                    if(tmp<0||g[tmp].end<x)
                        printf("Reject Free\n");
                    else
                    {
                        printf("Free from %d to %d\n",g[tmp].begin,g[tmp].end);
                        update(1,1,n,g[tmp].begin,g[tmp].end,0);
                        g.erase(g.begin()+tmp);
                    }
                }
            }
        }
        puts("");
    }
    return 0;
}

hdu 4614 

双二分+线段树

#include<iostream>
#include<stdio.h>
#include<cstdio>
using namespace std;
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define mid ((l+r)>>1)
#define maxn 111111
int set[maxn<<2],sum[maxn<<2];
int m,n,t;
void pushup(int rt)
{
    sum[rt]=sum[ls]+sum[rs];
}
void pushdown(int rt,int l,int r)
{
    if(set[rt]!=-1)
    {
        set[ls]=set[rs]=set[rt];
        sum[ls]=set[rt]==1?(mid-l+1):0;
        sum[rs]=set[rt]==1?(r-mid):0;
        set[rt]=-1;
    }
}
void ins(int rt,int l,int r,int L,int R,int w)
{
    if(L<=l&&r<=R)
    {
        set[rt]=w;
        sum[rt]=w==1?(r-l+1):0;
        return ;
    }
    pushdown(rt,l,r);
    if(L<=mid)ins(ls,l,mid,L,R,w);
    if(mid<R)ins(rs,mid+1,r,L,R,w);
    pushup(rt);
}
int q2(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)
        return sum[rt];
    pushdown(rt,l,r);
    int ans=0;
    if(L<=mid)ans+=q2(ls,l,mid,L,R);
    if(mid<R)ans+=q2(rs,mid+1,r,L,R);
    return ans;
}
int ansl,ansr;
void binl(int rr,int w)
{
    int l=ansl,r=rr;
    int xx=q2(1,1,n,ansl,r);
    w=min(w,xx);
    while(l<=r)
    {
        int _x=q2(1,1,n,mid,ansr);
//        printf("%d %d %d\n",l,r,_x);
        if(_x>=w){
            ansl=mid;
            l=mid+1;
        }
        else if(_x<w){
            r=mid-1;
        }
    }
}
void binr(int w)
{
    int l=ansl,r=n;
    int xx=q2(1,1,n,ansl,n);
    w=min(xx,w);
    while(l<=r)
    {
//            printf("l:%d r:%d\n",l,r);
        int _x=q2(1,1,n,ansl,mid);
        if(_x>=w){
            ansr=mid;
            r=mid-1;
        }
        else
        {
            l=mid+1;
        }
    }
}
void build(int rt,int l,int r)
{
    set[rt]=-1;
    sum[rt]=(r-l+1);
    if(l==r)return ;
    build(ls,l,mid);
    build(rs,mid+1,r);
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        int a,b,c;
        build(1,1,n);
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            if(a==1)
            {
                int tmp=q2(1,1,n,b+1,n);
                if(tmp==0)printf("Can not put any one.\n");
                else
                {
                    ansl=b+1;
                    binr(c);
                    binl(ansr,c);
                    printf("%d %d\n",ansl-1,ansr-1);
                    ins(1,1,n,ansl,ansr,0);
//                    printf("%d\n",q2(1,1,n,1,10));
                }
            }
            else if(a==2)
            {
//                printf("%d\n",q2(1,1,n,1,10));
                printf("%d\n",c-b+1-q2(1,1,n,b+1,c+1));
                ins(1,1,n,b+1,c+1,1);
            }
        }
        puts("");
    }
    return 0;
}


poj 1631

#include<stdio.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ls (rt<<1)
#define rs  ((rt<<1)|1)
#define mid ((l+r)>>1)
#define maxn 44444
int mmax[maxn<<2];
void ins(int rt,int l,int r,int L,int R,int w)
{
    if(l==r)
    {
        mmax[rt]=w;
        return ;
    }
    if(L<=mid)ins(ls,l,mid,L,R,w);
    else if(mid<R)ins(rs,mid+1,r,L,R,w);
    mmax[rt]=max(mmax[ls],mmax[rs]);
}
int query(int rt,int l,int r,int L,int R)
{
    if(L<=l&&r<=R)
    {
        return mmax[rt];
    }
    int ans=0;
    if(L<=mid)ans=max(ans,query(ls,l,mid,L,R));
    if(mid<R)ans=max(ans,query(rs,mid+1,r,L,R));
    return ans;
}
void build(int rt,int l,int r)
{
    mmax[rt]=0;
    if(l==r)return ;
    build(ls,l,mid);
    build(rs,mid+1,r);
}
int main()
{
    int t,n,x,ans,tmp;
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        scanf("%d",&n);
        build(1,1,n);
        for(int i=1;i<=n;++i){
            scanf("%d",&x);
             tmp=query(1,1,n,1,x);
//            printf("tmp:%d\n",tmp);
            ins(1,1,n,x,x,tmp+1);
            ans=max(tmp+1,ans);
        }
        printf("%d\n",ans);
    }
    
    return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值