线段树专题

线段树:旨在自己看,题目来源与报告来自http://www.notonlysuccess.com/index.php/segment-tree-complete/是某位大牛写的,很犀利。。。

(1):单点更新

         HDU 1166敌兵布阵                       http://acm.hdu.edu.cn/showproblem.php?pid=116

View Code
#include<cstdio>

#include<cstdlib>

#include<cmath>

#include<cstring>

#define MAXN 50005

int seg_tree[MAXN<<2];

void build_tree(int l,int r,int id);

int query_tree(int left,int right,int l,int r,int id);

void update_point_tree(int left,int right,int value,int l,int r,int id);

void push_up_tree(int id);

int main()

{

    int tcase,n,i,left,right,value;

    char str[20];

    while(scanf("%d",&tcase)==1)

    {

        for(i=1;i<=tcase;i++)

        {

            printf("Case %d:\n",i);

          scanf("%d",&n);

              build_tree(1,n,1);

        while(scanf("%s",str)!=EOF)

        {

            if(!strcmp(str,"Query"))

            {

                scanf("%d%d",&left,&right);

                printf("%d\n",query_tree(left,right,1,n,1));

            }

            if(!strcmp(str,"Add"))

            {

                scanf("%d%d",&left,&value);

                update_point_tree(left,left,value,1,n,1);



            }

            if(!strcmp(str,"Sub"))

            {

                scanf("%d%d",&left,&value);

                update_point_tree(left,left,-value,1,n,1);

            }

            if(!strcmp(str,"End"))

                break;

        }

        



        }



    }

}

void build_tree(int l,int r,int id)

{

    if(l==r)

    {

        scanf("%d",&seg_tree[id]);

        return ;

    }

    int mid=(l+r)/2;

    build_tree(l,mid,id<<1);

    build_tree(mid+1,r,id<<1|1);

   push_up_tree(id);

    

}

int query_tree(int left,int right,int l,int r,int id)

{

    if(left<=l&&right>=r)

        return seg_tree[id];

    int mid=(l+r)>>1,ret=0;

    if(left<=mid)

        ret+=query_tree(left,right,l,mid,id<<1);

    if(right>mid)

        ret+=query_tree(left,right,mid+1,r,id<<1|1);

    return ret;

}

void update_point_tree(int left,int right,int value,int l,int r,int id)

{

    if(l==r)

    {    seg_tree[id]+=value;

    return ;}

    int mid=(l+r)>>1;

    if(left<=mid)

        update_point_tree(left,right,value,l,mid,id<<1);

    else 

        update_point_tree(left,right,value,mid+1,r,id<<1|1);

    push_up_tree(id);

    



}

void push_up_tree(int id)

{

    seg_tree[id]=seg_tree[id<<1]+seg_tree[id<<1|1];

}

         HDU 1754 I Hate it                       http://acm.hdu.edu.cn/showproblem.php?pid=1754

View Code
#include<cstdio>

#include<cstdlib>

#include<cmath>

#include<cstring>

#define MAXN 200005

int seg_tree[MAXN<<2];

void build_tree(int l,int r,int id);

int query_tree(int left,int right,int l,int r,int id);

void update_point_tree(int left,int right,int value,int l,int r,int id);

void push_up_tree(int id);

int main()

{

int tcase,n,i,left,right,value,m;

char str[20];

while(scanf("%d%d",&n,&m)==2)

{

build_tree(1,n,1);

while(m--)

{

scanf("%s",str);

if(str[0]=='Q')

{

scanf("%d%d",&left,&right);

printf("%d\n",query_tree(left,right,1,n,1));

}

if(str[0]=='U')

{

scanf("%d%d",&left,&value);

update_point_tree(left,right,value,1,n,1);

}

}

}

}

void build_tree(int l,int r,int id)

{

if(l==r)

{

scanf("%d",&seg_tree[id]);

return ;

}

int mid=(l+r)/2;

build_tree(l,mid,id<<1);

build_tree(mid+1,r,id<<1|1);

push_up_tree(id);



}

int query_tree(int left,int right,int l,int r,int id)

{

if(left<=l&&right>=r)

return seg_tree[id];

int mid=(l+r)>>1,ret0=0,ret1=0;

if(left<=mid)

ret0=query_tree(left,right,l,mid,id<<1);

if(right>mid)

ret1=query_tree(left,right,mid+1,r,id<<1|1);

return ret0>=ret1?ret0:ret1;

}

void update_point_tree(int left,int right,int value,int l,int r,int id)

{

if(l==r)

{    seg_tree[id]=value;

return ;}

int mid=(l+r)>>1;

if(left<=mid)

update_point_tree(left,right,value,l,mid,id<<1);

else 

update_point_tree(left,right,value,mid+1,r,id<<1|1);

push_up_tree(id);

}

void push_up_tree(int id)

{

int temp1,temp2;

temp1=seg_tree[id<<1];

temp2=seg_tree[id<<1|1];

seg_tree[id]=(temp1>=temp2?temp1:temp2);

}

        hdu Minimum Inversion Number     http://acm.hdu.edu.cn/showproblem.php?pid=1394

View Code
#include<cstdio>

#include<cstdlib>

#include<cstdlib>

#include<cstring>

#define MAXN  5010

int seg_tree[MAXN<<2];

void build_tree(int l,int r,int id);

int query_tree(int left,int right,int l,int r,int id);

void update_tree(int left,int right,int l,int r,int id);

void push_up_tree(int id);

int x[MAXN];

int main()

{

    int n,i,j,k,sum;

    while(scanf("%d",&n)==1)

    {

        sum=0;

        build_tree(0,n-1,1);

        for(i=0;i<n;i++)

        {

            scanf("%d",x+i);

            

        }

        for(i=n-1;i>=0;i--)

        {

            sum+=query_tree(0,x[i],0,n-1,1);

            update_tree(x[i],x[i],0,n-1,1);

        }

        int ret=sum;

        for(i=0;i<n;i++)

        {

            sum+=n-1-x[i]-x[i];

            if(ret>sum)

                ret=sum;

        }

        printf("%d\n",ret);



    }

}

void build_tree(int l,int r,int id)

{

    if(l==r)

    {seg_tree[id]=0;

    return ;

    }

    int m=(l+r)>>1;

    build_tree(l,m,id<<1);

    build_tree(m+1,r,id<<1|1);

    push_up_tree(id);

}

int query_tree(int left,int right,int l,int r,int id)

{

    if(left<=l&&right>=r)

        return seg_tree[id];

    int m=(l+r)>>1,ret=0;

    if(left<=m)

        ret+=query_tree(left,right,l,m,id<<1);

    if(right>m)

        ret+=query_tree(left,right,m+1,r,id<<1|1);

    return ret;

}

void update_tree(int left,int right,int l,int r,int id)

{

    if(l==r)

    {seg_tree[id]++;

    return ;

    }

    int m=(l+r)>>1;

    if(left<=m)

        update_tree(left,right,l,m,id<<1);

    else update_tree(left,right,m+1,r,id<<1|1);

    push_up_tree(id);



}

void push_up_tree(int id)

{

    seg_tree[id]=seg_tree[id<<1]+seg_tree[id<<1|1];

}

        HDU Billboard                              http://acm.hdu.edu.cn/showproblem.php?pid=2795

View Code
#include<cstdio>

#include<cstdlib>

#include<cmath>

#include<cstring>

#define MAXN 200002

void build_tree(int l,int r,int id);

void push_up_tree(int id);

void update_tree(int value,int *x,int l,int r,int id);

int m_max(int a,int b);

int seg_tree[MAXN<<2];

int h,w,n;

int main() 

{

    int temp,value,x;

    while(scanf("%d%d%d",&h,&w,&n)==3)

    {

        h=(h>=n?n:h);

        build_tree(1,h,1);

        while(n--)

        {

            scanf("%d",&value);

            if(value>seg_tree[1])

            {

                printf("-1\n");

            }

            else 

            {

                update_tree(value,&x,1,h,1);

                printf("%d\n",x);

            }



            

        }





    }

}

void build_tree(int l,int r,int id)

{

    if(l==r)

    {

        seg_tree[id]=w;

        return ;

    }

    int m=(l+r)>>1;

    build_tree(l,m,id<<1);

    build_tree(m+1,r,id<<1|1);

    push_up_tree(id);

    

}

void push_up_tree(int id)

{

    seg_tree[id]=m_max(seg_tree[id<<1],seg_tree[id<<1|1]);

}

int m_max(int a,int b)

{

    return a>=b?a:b;

}

void update_tree(int value,int *x,int l,int r,int id)

{

    if(l==r)

    {

        *x=l;

        seg_tree[id]-=value;

        return ;

    }

    int m=(l+r)>>1;

    if(seg_tree[id<<1]>=value)

        update_tree(value,x,l,m,id<<1);

    else update_tree(value,x,m+1,r,id<<1|1);

    push_up_tree(id);

}

       poj Buy Tickets                             http://poj.org/problem?id=2828

View Code
#include<cstdio>

#include<cstdlib>

#include<cmath>

#include<cstring>

#define MAXN 200005

int seg_tree[MAXN<<2];

void build_tree(int l,int r,int id);

void push_up_tree(int id);

void update_tree(int left,int right,int l,int r,int id);

int ans[MAXN],cur;

struct Node

{

    int i;

    int num;

};

Node temp[MAXN];

int main()

{

        int n,i,j,k;

    while(scanf("%d",&n)==1)

    {

        build_tree(1,n,1);

        for(i=1;i<=n;i++)

        {scanf("%d%d",&temp[i].i,&temp[i].num);}

        for(i=n;i>0;i--)

           {

               cur=temp[i].num;

               update_tree(temp[i].i+1,n,1,n,1);



                   }

        for(i=1;i<=n;i++)

        {if(i-1) printf(" ");

            printf("%d",ans[i]);

        }

        printf("\n");



    }



   

}

void build_tree(int l,int r,int id)

{

        if(l==r)

    {

        seg_tree[id]=1;

        return ;

    }

  int m=(l+r)>>1;

  build_tree(l,m,id<<1);

  build_tree(m+1,r,id<<1|1);

  push_up_tree(id);

    

}

void push_up_tree(int id)

{

    seg_tree[id]=seg_tree[id<<1]+seg_tree[id<<1|1];

}

void update_tree(int left,int right,int l,int r,int id)

{

    if(l==r)

    {

        seg_tree[id]--;

        ans[l]=cur;



        return ;

    }

    int m=(l+r)>>1;

        if(left<=seg_tree[id<<1])

        update_tree(left,right,l,m,id<<1);

    else 

    {

        left-=seg_tree[id<<1];

        update_tree(left,right,m+1,r,id<<1|1);

    }

    push_up_tree(id);

}

     poj Who Gets the Most Candies?         http://poj.org/problem?id=2886

View Code
#include<cstdio>

#include<cstdlib>

#include<cmath>

#include<memory.h>

int seg_tree[500010<<2];

void build_tree(int l,int r,int id);

void push_tree_up(int id);

void update_tree(int value,int l,int r,int id);

int f[500010];

void get_f();

int num[500010],h;

char str[500010][10];

int cur_n,cur_i,next_i,ans,ans1;

int main()

{

    int n,k,i,j,cur,temp;

    //freopen("d:\\2.txt","r",stdin);

    //freopen("d:\\3.txt","w",stdout);

    memset(f,0,sizeof(f));

    get_f();

    while(scanf("%d%d%*c",&n,&k)!=EOF)

    {

        for(i=1;i<=n;i++)

            scanf("%s%d",str[i],num+i);

        cur_n=n;

        cur_i=n;

        next_i=k;

        build_tree(1,n,1);

        ans=0;

        ans1=1;

        h=1;

        for(i=1;i<=n;i++)

        {

        //  printf("cur_i=%d next_i=%d",cur_i,next_i);

                  if(next_i>=0)

                      cur_i--;

                  cur=(cur_i+next_i%cur_n+cur_n)%cur_n;

              //   printf(" cur=%d\n",cur);

            update_tree(cur+1,1,n,1);

            cur_i=cur;

            h++;





        }

        printf("%s %d\n",str[ans1],ans);



    }



}

void build_tree(int l,int r,int id)

{

    if(l==r)

    {

        seg_tree[id]=1;

        return ;

    }

    int mid=(l+r)>>1;

    build_tree(l,mid,id<<1);

    build_tree(mid+1,r,id<<1|1);

    push_tree_up(id);

}

void push_tree_up(int id)

{

    seg_tree[id]=seg_tree[id<<1]+seg_tree[id<<1|1];

}

void update_tree(int value,int l,int r,int id)

{

    if(l==r)

    {

        seg_tree[id]--;

    // printf("tree[id]=%d",seg_tree[id]);

    //    printf("l=%d\n",l);

            next_i=num[l];

        cur_n--;

        if(ans<f[h])

        {



        ans=f[h];

        ans1=l;

        }

        return ;

    }

    int mid=l+r>>1;

    if(value<=seg_tree[id<<1])

    {

        update_tree(value,l,mid,id<<1);

    }

    else

    {

        update_tree(value-seg_tree[id<<1],mid+1,r,id<<1|1);

    }

    push_tree_up(id);

}

void get_f()

{



    int i,j;

    for(i=1;i<=500000;i++)

    for(j=1;i*j<=500000;j++)

    {

        f[i*j]++;

    }

}

 (2):成段更新:

      1:hdu 1698 just a hook                   http://acm.hdu.edu.cn/showproblem.php?pid=1698

View Code
#include<cstdio>

#include<cstdlib>

#include<cmath>

#include<cstring>

#define MAXN 200010

int color[MAXN<<2];

int tree[MAXN<<2];

void build_tree(int l,int r,int id);

void up_date_tree(int left,int right,int l,int r,int id,int value);

void push_down(int l,int r,int id);

void push_up_tree(int id);

int main()

{

    int tcase,i,j,k,n,value,left,right,num;

    while(scanf("%d",&tcase)==1)

    {

        for(j=1;j<=tcase;j++)

        {

            scanf("%d",&n);

            build_tree(1,n,1);

            scanf("%d",&num);

            for(i=0;i<num;i++)

            {



              scanf("%d%d%d",&left,&right,&value);

              up_date_tree(left,right,1,n,1,value);

            }

            printf("Case %d: The total value of the hook is %d.\n",j,tree[1]);

        }

    }



}

void build_tree(int l,int r,int id)

{

    color[id]=0;

    if(l==r)

    {

        tree[id]=1;

        return ;

    }

    tree[id]=r-l+1;

    int mid=l+r>>1;

    build_tree(l,mid,id<<1);

    build_tree(mid+1,r,id<<1|1);



}

void up_date_tree(int left,int right,int l,int r,int id,int value)

{

    if(left<=l&&right>=r)

    {

        tree[id]=(r-l+1)*value;

        color[id]=value;

        return ;

    }

    push_down(l,r,id);

    int mid=l+r>>1;

   if(left<=mid) up_date_tree(left,right,l,mid,id<<1,value);

   if(right>mid) up_date_tree(left,right,mid+1,r,id<<1|1,value);

   push_up_tree(id);

}

void push_down(int l,int r,int id)

{

    if(color[id])

    {

        color[id<<1]=color[id];

        color[id<<1|1]=color[id];

        int mid=l+r>>1;

        tree[id<<1]=(mid-l+1)*color[id];

        tree[id<<1|1]=(r-mid)*color[id];







    }

    color[id]=0;

}

void push_up_tree(int id)

{

    tree[id]=tree[id<<1]+tree[id<<1|1];

}

 (3): poj 3468 A Simple Problem with Integers   http://poj.org/problem?id=3468

View Code
#include<cstdio>

#include<cstdlib>

#include<cmath>

#include<cstring>

#define MAXN 100010

__int64 color[MAXN<<2];

__int64 tree[MAXN<<2];

int n,num;

void build_tree(int l,int r,int id);

void push_up_tree(int id);

__int64 query_tree(int left,int right,int l,int r,int id);

void update_tree(int left,int right,int l,int r,int id,__int64 value);

void push_down(int l,int r,int id);

int main()

{

    int i,left,right;

    __int64 value;

    char str[10];

    while(scanf("%d%d",&n,&num)==2)

    {



        build_tree(1,n,1);

        //printf("%I64d\n",tree[4]);

        for(i=1;i<=num;i++)

        {

            scanf("%s",str);

            if(str[0]=='Q')

            {

                scanf("%d%d",&left,&right);

               // printf("%s %d %d\n",str,left,right);

                printf("%I64d\n",query_tree(left,right,1,n,1));

            }

            if(str[0]=='C')

            {

                scanf("%d%d%I64d",&left,&right,&value);

              update_tree(left,right,1,n,1,value);

            }

        }



    }



}

void build_tree(int l,int r,int id)

{

    color[id]=0;

    if(l==r)

    {

        scanf("%I64d",&tree[id]);

        return ;

    }

    int mid=l+r>>1;

    build_tree(l,mid,id<<1);

    build_tree(mid+1,r,id<<1|1);

    push_up_tree(id);

}

void push_up_tree(int id)

{

    tree[id]=tree[id<<1]+tree[id<<1|1];

}

__int64 query_tree(int left,int right,int l,int r,int id)

{

    if(left<=l&&right>=r)

        return tree[id];

    push_down(l,r,id);

    int mid=l+r>>1;__int64 ret0=0;

    if(left<=mid)

        ret0+=query_tree(left,right,l,mid,id<<1);

    if(right>mid)

        ret0+=query_tree(left,right,mid+1,r,id<<1|1);

    return ret0;

}

void push_down(int l,int r,int id)

{

    if(color[id])

    {

        int mid=l+r>>1;

        color[id<<1]+=color[id];

        color[id<<1|1]+=color[id];

        tree[id<<1]+=(mid-l+1)*color[id];

        tree[id<<1|1]+=(r-mid)*color[id];

        color[id]=0;

    }

}

void update_tree(int left,int right,int l,int r,int id, __int64 value)

{

      if(left<=l&&right>=r)

      {

          color[id]+=value;

          tree[id]+=(r-l+1)*value;

          return ;

      }

      push_down(l,r,id);

      int mid=l+r>>1;

      if(left<=mid)

      {

         update_tree(left,right,l,mid,id<<1,value);

      }

      if(right>mid)

          update_tree(left,right,mid+1,r,id<<1|1,value);

      push_up_tree(id);



}

 (4):poj 3255 Help with Intervals                                                          http://poj.org/problem?id=3225

View Code
#include<cstdio>

#include<cstdlib>

#include<cmath>

#include<cstring>

#define MAXN 131072

int c_cover[MAXN<<2],c_xor[MAXN<<2];

bool hash[MAXN+10];

void update(char op,int left,int right,int l,int r,int id);

void f_xor(int id);

void push_down(int id);

void push_down(int id);

void query(int l,int r,int id);

int main()

{

    char op,c_left,c_right;

    int i,left,right;

    c_xor[1]=0;

        c_cover[1]=0;

    while(~scanf("%c %c%d,%d%c\n",&op,&c_left,&left,&right,&c_right))

    {

        left<<=1;

        right<<=1;



        if(c_left=='(')

            left++;

        if(c_right==')')

            right--;

        if(left>right)

        {

            if(op=='C'||op=='I')

            c_cover[1]=c_xor[1]=0;

        }

        else update(op,left,right,0,MAXN,1);

    }

        query(0,MAXN,1);

        int a=-1,b;

        bool flag=false;

        for(i=0;i<=MAXN;i++)

        {

            if(hash[i])

               {



                   b=i;

                   if(a==-1)a=i;





               }

           else if(a!=-1)

           {

               if(flag)

               printf(" ");

               printf("%c%d,%d%c",a&1?'(':'[',a>>1,(b+1)>>1,b&1?')':']');

                   flag=true;

                   a=-1;



           }

        }

        if(!flag)

        printf("empty set");

        puts("");





}

void update(char op,int left,int right,int l,int r,int id)

{

     if(left<=l&&right>=r)

     {

         if(op=='U')

         {

             c_cover[id]=1;

             c_xor[id]=0;





         }

         else if(op=='D')

         {

             c_cover[id]=0;

             c_xor[id]=0;

         }

         else if(op=='S'||op=='C')

         {

         f_xor(id);

         }

         return ;

    }

     push_down(id);

     int mid=(l+r)>>1;

     if(left<=mid)

         update(op,left,right,l,mid,id<<1);

     else if(op=='I'||op=='C')

     {

         c_cover[id<<1]=0;

         c_xor[id<<1]=0;

     }

     if(right>mid)

     {

         update(op,left,right,mid+1,r,id<<1|1);

     }

     else if(op=='I'||op=='C')

     {

         c_cover[id<<1|1]=0;

         c_xor[id<<1|1]=0;

     }















}

void f_xor(int id)

{

    if(c_cover[id]!=-1)

        c_cover[id]^=1;

    else

        c_xor[id]^=1;

}

void push_down(int id)

{

    if(c_cover[id]!=-1)

    {

        c_cover[id<<1]=c_cover[id<<1|1]=c_cover[id];

        c_xor[id<<1]=c_xor[id<<1|1]=0;

        c_cover[id]=-1;



    }

     if(c_xor[id])

    {

        f_xor(id<<1);

        f_xor(id<<1|1);

        c_xor[id]=0;

    }

}

void query(int l,int r,int id)

{

    if(c_cover[id]==1)

    {

        int i;

        for(i=l;i<=r;i++)

        {

            hash[i]=1;

        }

        return ;

    }

    else if(c_cover[id]==0)

        return ;

    if(l==r)

        return ;

      push_down(id);

    int mid=(l+r)>>1;

    query(l,mid,id<<1);

    query(mid+1,r,id<<1|1);

}

 (5):poj 3667 Hotel                     http://poj.org/problem?id=3667

View Code
#include<cstdio>

#include<cstdlib>

#include<cmath>

#include<cstring>

#define MAXN 55555

int lmax[MAXN<<2],rmax[MAXN<<2],mmax[MAXN<<2],cover[MAXN<<2];

void build(int l,int r,int id);

void update(int left,int right,int l,int r,int id,int value);

int query(int value,int l,int r,int id);

void pushdown(int id,int l,int r);

void pushup(int id,int l,int r);

int max(int a,int b);

int main()

{

     int n,m,op,value,left,right,i;

     while(scanf("%d%d",&n,&m)==2)

     {

         build(1,n,1);

         while(m--)

         {

             scanf("%d",&op);

             if(op==1)

             {

                 scanf("%d",&value);

                 if(value>mmax[1])

                     printf("0\n");

                 else

                 {

                   left=query(value,1,n,1);

                   printf("%d\n",left);

                   update(left,left+value-1,1,n,1,0);



                 }

             }

             else

             {

                 scanf("%d%d",&left,&right);

                 update(left,left+right-1,1,n,1,1);

             }

         }





     }





}

void build(int l,int r,int id)

{

    lmax[id]=rmax[id]=mmax[id]=(r-l+1);

    cover[id]=-1;

    if(l==r)

        return;

        int mid=l+r>>1;

    build(l,mid,id<<1);

    build(mid+1,r,id<<1|1);

}

void update(int left,int right,int l,int r,int id,int value)

{

    if(left<=l&&right>=r)

    {

        cover[id]=value;

        rmax[id]=mmax[id]=lmax[id]=(r-l+1)*value;

        return ;





    }

    if(l==r)

    return ;

    int mid=l+r>>1;

    pushdown(id,l,r);

    if(left<=mid)

        update(left,right,l,mid,id<<1,value);

    if(right>mid)

        update(left,right,mid+1,r,id<<1|1,value);

    pushup(id,l,r);









}

int query(int value,int l,int r ,int id)

{

    if(l==r)

        return l;

        pushdown(id,l,r);

    int mid=l+r>>1;

    if(mmax[id<<1]>=value)

          return query(value,l,mid,id<<1);

    else if(rmax[id<<1]+lmax[id<<1|1]>=value)

        return mid-rmax[id<<1]+1;

    else return query(value,mid+1,r,id<<1|1);

    //pushup(id,l,r);

}

void pushdown(int id,int l,int r)

{

    if(cover[id]!=-1)

    {

        int mid=l+r>>1;

        cover[id<<1]=cover[id<<1|1]=cover[id];

        lmax[id<<1]=mmax[id<<1]=rmax[id<<1]=(mid-l+1)*cover[id];

        lmax[id<<1|1]=rmax[id<<1|1]=mmax[id<<1|1]=(r-mid)*cover[id];

        cover[id]=-1;

    }

}

void pushup(int id,int l,int r)

{

    int mid=r+l>>1;

   rmax[id]=rmax[id<<1|1]+((rmax[id<<1|1]==r-mid)?rmax[id<<1]:0);

   lmax[id]=lmax[id<<1]+((lmax[id<<1]==mid-l+1)?lmax[id<<1|1]:0);

   mmax[id]=max(max(mmax[id<<1],mmax[id<<1|1]),rmax[id<<1]+lmax[id<<1|1]);

}

int max(int a,int b)

{

    return a>=b?a:b;

}

 

 

你可能感兴趣的:(线段树)