zoukankan      html  css  js  c++  java
  • HNCU专题训练_线段树(2)

    1.统计颜色,或运算的运用
    2.区间第k大数
    3.一个很经典的题
    5.求区间相等数字的个数
    6.RMQ模板题,区间最大值和最小值的差


    1.很好的思路,用或运算来避免左右儿子树总相同颜色的情况。由于
    T颜色种类最多30种,__int64 足够用了。
    注意初始化就行。

    5.关键是写对make_up()这个函数,向上更新需要考虑的问题。经典题型。

    1001

      1 /*
      2 
      3 求区间[l,r]中,颜色的总类。
      4 如何避免重复?----或运算。
      5 
      6 */
      7 
      8 #include<iostream>
      9 #include<cstdio>
     10 #include<cstdlib>
     11 #include<algorithm>
     12 #define HH 1
     13 using namespace std;
     14 
     15 
     16 struct node
     17 {
     18     int l;
     19     int r;
     20     int color;
     21     __int64 num;
     22 }f[100003*8];
     23 
     24 
     25 void build(int l,int r,int n)
     26 {
     27     int mid=(l+r)/2;
     28     f[n].l=l;
     29     f[n].r=r;
     30     f[n].color=0;
     31     f[n].num=1<<1;
     32     if(l==r)
     33     return ;
     34     build(l,mid,n*2);
     35     build(mid+1,r,n*2+1);
     36 }
     37 
     38 void make_down(int n)
     39 {
     40     f[n*2].color=f[n*2+1].color=HH;
     41 
     42     f[n*2].num=f[n*2+1].num=f[n].num;
     43 
     44     f[n].color=0;
     45     f[n].num=0;
     46 }
     47 
     48 void update(int l,int r,int num,int n)
     49 {
     50     int mid=(f[n].l+f[n].r)/2;
     51 
     52     if(f[n].l==l && f[n].r==r)
     53     {
     54         f[n].color=HH;
     55         f[n].num=1<<num;
     56         return;
     57     }
     58     if(f[n].color==HH)
     59     make_down(n);
     60     if(mid>=r)
     61     update(l,r,num,n*2);
     62     else if(mid<l)
     63     update(l,r,num,n*2+1);
     64     else
     65     {
     66         update(l,mid,num,n*2);
     67         update(mid+1,r,num,n*2+1);
     68     }
     69     f[n].num=f[n*2].num|f[n*2+1].num;
     70 }
     71 
     72 __int64 query(int l,int r,int n)
     73 {
     74     int mid=(f[n].l+f[n].r)/2;
     75     __int64 cur=0;
     76     if(f[n].l==l && f[n].r==r)
     77     {
     78         return f[n].num;
     79     }
     80     if(f[n].color==HH)
     81     make_down(n);
     82     if(mid>=r)
     83     cur=query(l,r,n*2);
     84     else if(mid<l)
     85     cur=query(l,r,n*2+1);
     86     else
     87     {
     88         cur=query(l,mid,n*2)|query(mid+1,r,n*2+1);
     89     }
     90     f[n].num=f[n*2].num|f[n*2+1].num;
     91     return  cur;
     92 
     93 }
     94 
     95 int Get_num(__int64 num) //得到1的个数  很优化的算法。
     96 {
     97     int count=0;
     98     while(num)
     99     {
    100         ++count;
    101         num=(num-1)&num;
    102     }
    103     return count;
    104 }
    105 
    106 void make_ini(int L,int T,int O)
    107 {
    108     int A,B,num,hxl;
    109     __int64 tmp;
    110     char a[5];
    111     while(O--)
    112     {
    113         scanf("%s",a);
    114         if(a[0]=='C')
    115         {
    116             scanf("%d%d%d",&A,&B,&num);
    117             if(A>B)
    118             {
    119                 hxl=A;
    120                 A=B;
    121                 B=hxl;
    122             }
    123             if(num<=T)
    124             update(A,B,num,1);
    125         }
    126         else if(a[0]=='P')
    127         {
    128             scanf("%d%d",&A,&B);
    129             if(A>B)
    130             {
    131                 hxl=A;
    132                 A=B;
    133                 B=hxl;
    134             }
    135             tmp=query(A,B,1);
    136             printf("%d
    ",Get_num(tmp));
    137         }
    138     }
    139 }
    140 
    141 int main()
    142 {
    143     int L,T,O;
    144     while(scanf("%d%d%d",&L,&T,&O)>0)
    145     {
    146         build(1,L,1);
    147         make_ini(L,T,O);
    148     }
    149     return 0;
    150 }
    View Code

    1002

     1 /*
     2 第k小的数
     3 
     4 */
     5 
     6 #include<iostream>
     7 #include<cstdio>
     8 #include<cstdlib>
     9 #include<cstring>
    10 #include<algorithm>
    11 #define NN 100010
    12 using namespace std;
    13 
    14 
    15 int toleft[30][NN];
    16 int Tree[30][NN];
    17 int Sort[NN];
    18 
    19 
    20 void build(int l,int r,int dep)
    21 {
    22     int mid=(l+r)/2,sum=mid-l+1,lpos,rpos,i;
    23     if(l==r) return ;
    24     for(i=l;i<=r;i++)
    25     if(Tree[dep][i]<Sort[mid]) sum--;
    26     lpos=l;
    27     rpos=mid+1;
    28     for(i=l;i<=r;i++)
    29     {
    30         if(Tree[dep][i]<Sort[mid])
    31         {
    32             Tree[dep+1][lpos++]=Tree[dep][i];
    33         }
    34         else if(Tree[dep][i]==Sort[mid] && sum>0)
    35         {
    36             Tree[dep+1][lpos++]=Tree[dep][i];
    37             sum--;
    38         }
    39         else
    40         {
    41             Tree[dep+1][rpos++]=Tree[dep][i];
    42         }
    43         toleft[dep][i]=toleft[dep][l-1]+lpos-l;
    44     }
    45     build(l,mid,dep+1);
    46     build(mid+1,r,dep+1);
    47 }
    48 
    49 int query(int L,int R,int l,int r,int k,int dep)
    50 {
    51     int mid=(L+R)/2,newl,newr,cur;
    52     if(l==r) return Tree[dep][l];
    53     cur=toleft[dep][r]-toleft[dep][l-1];
    54     if(cur>=k)
    55     {
    56         newl=L+toleft[dep][l-1]-toleft[dep][L-1];
    57         newr=newl+cur-1;
    58         return query(L,mid,newl,newr,k,dep+1);
    59     }
    60     else
    61     {
    62         newr=r+(toleft[dep][R]-toleft[dep][r]);
    63         newl=newr-(r-l-cur);
    64         return query(mid+1,R,newl,newr,k-cur,dep+1);
    65     }
    66 }
    67 
    68 void make_ini(int N,int M)
    69 {
    70     int l,r,k;
    71     while(M--)
    72     {
    73         scanf("%d%d%d",&l,&r,&k);
    74         printf("%d
    ",query(1,N,l,r,k,0));
    75     }
    76 }
    77 
    78 int main()
    79 {
    80     int N,M,i;
    81     while(scanf("%d%d",&N,&M)>0)
    82     {
    83         for(i=1;i<=N;i++)
    84         {
    85             scanf("%d",&Tree[0][i]);
    86             Sort[i]=Tree[0][i];
    87         }
    88         sort(Sort+1,Sort+1+N);
    89         build(1,N,0);
    90         make_ini(N,M);
    91     }
    92     return 0;
    93 }
    View Code

    1003

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cstdlib>
      4 #define HH 1 //纯色
      5 using namespace std;
      6 
      7 struct st
      8 {
      9     __int64 l;
     10     __int64 r;
     11     __int64 num;
     12     __int64 color;
     13     __int64 max;
     14 }f[100003*4];
     15 __int64 date[100003];
     16 
     17 void build(__int64 l,__int64 r,__int64 n)
     18 {
     19     __int64 mid=(l+r)/2;
     20     f[n].l=l;
     21     f[n].r=r;
     22     f[n].color=0;
     23     f[n].num=0;
     24     if(l==r)
     25     {
     26         f[n].max=date[l];
     27         return;
     28     }
     29     build(l,mid,n*2);
     30     build(mid+1,r,n*2+1);
     31     f[n].max=f[n*2].max+f[n*2+1].max;
     32 }
     33 
     34 void make_down(__int64 n)
     35 {
     36 
     37     f[n*2].num+=f[n].num;
     38     f[n*2].color=HH;
     39     f[n*2].max+=f[n].num*(f[n*2].r-f[n*2].l+1);
     40 
     41     f[n*2+1].num+=f[n].num;
     42     f[n*2+1].color=HH;
     43     f[n*2+1].max+=f[n].num*(f[n*2+1].r-f[n*2+1].l+1);
     44 
     45     f[n].color=0;f[n].num=0;
     46 }
     47 
     48 void update(__int64 l,__int64 r,__int64 num,__int64 n)
     49 {
     50     __int64 mid=(f[n].l+f[n].r)/2;
     51     if(f[n].l==l && f[n].r==r)
     52     {
     53         f[n].num+=num;
     54         f[n].max+=num*(f[n].r-f[n].l+1);
     55         f[n].color=HH;
     56         return ;
     57     }
     58     if(f[n].color==HH)
     59         make_down(n);
     60     if(mid>=r)
     61         update(l,r,num,n*2);
     62     else if(mid<l)
     63         update(l,r,num,n*2+1);
     64     else
     65     {
     66         update(l,mid,num,n*2);
     67         update(mid+1,r,num,n*2+1);
     68     }
     69     f[n].max=f[n*2].max+f[n*2+1].max;
     70 }
     71 
     72 __int64 query(__int64 l,__int64 r,__int64 n)
     73 {
     74     __int64 mid=(f[n].l+f[n].r)/2;
     75     __int64 cur=0;
     76     if(f[n].l==l && f[n].r==r)
     77     {
     78         return f[n].max;
     79     }
     80     if(f[n].color==HH)
     81         make_down(n);
     82     if(mid>=r)
     83         cur= query(l,r,n*2);
     84     else if(mid<l)
     85         cur= query(l,r,n*2+1);
     86     else
     87     {
     88         cur+= query(l,mid,n*2);
     89         cur+=query(mid+1,r,n*2+1);
     90     }
     91     f[n].max=f[n*2].max+f[n*2+1].max;
     92     return cur;
     93 }
     94 
     95 int main()
     96 {
     97     __int64 n,q,i,l,r,num;
     98     char a[5];
     99     while(scanf("%I64d%I64d",&n,&q)>0)
    100     {
    101         for(i=1;i<=n;i++)
    102             scanf("%I64d",&date[i]);
    103         build(1,n,1);
    104         while(q--)
    105         {
    106             scanf("%s",a);
    107             if(a[0]=='Q')
    108             {
    109                 scanf("%I64d%I64d",&l,&r);
    110                 printf("%I64d
    ",query(l,r,1));
    111             }
    112             else if(a[0]=='C')
    113             {
    114                 scanf("%I64d%I64d%I64d",&l,&r,&num);
    115                 update(l,r,num,1);
    116             }
    117         }
    118     }
    119     return 0;
    120 }
    View Code

    1005

      1 /*
      2 
      3 求区间[l,r]中,相等数字的最大个数
      4 试一试能不能A。
      5 
      6 */
      7 
      8 #include<iostream>
      9 #include<cstdio>
     10 #include<cstdlib>
     11 #include<algorithm>
     12 using namespace std;
     13 
     14 
     15 
     16 struct node
     17 {
     18     int l;
     19     int r;
     20     int lmax,rmax,max;
     21     int lnum,rnum;
     22     int len;
     23 }f[100003*4];
     24 int Date[100003];
     25 
     26 int hmax(int x,int y)
     27 {
     28     return x>y? x: y;
     29 }
     30 
     31 int hmin(int x,int y)
     32 {
     33     return x>y? y:x;
     34 }
     35 
     36 void make_up(node *father,node *l_child,node *r_child)
     37 {
     38     father->lnum=l_child->lnum;
     39     father->rnum=r_child->rnum;
     40     if(l_child->rnum!=r_child->lnum)
     41     {
     42         father->lmax=l_child->lmax;
     43         father->rmax=r_child->rmax;
     44         father->max=hmax(hmax(father->lmax,father->rmax),
     45                          hmax(l_child->max,r_child->max));
     46     }
     47     else
     48     {
     49         father->lmax=(l_child->lmax==l_child->len)? l_child->lmax+r_child->lmax:l_child->lmax;
     50         father->rmax=(r_child->rmax==r_child->len)? r_child->rmax+l_child->rmax:r_child->rmax;
     51         father->max= hmax(hmax(father->lmax,father->rmax),
     52                           hmax(l_child->max,
     53                                hmax(r_child->max,l_child->rmax+r_child->lmax)));
     54     }
     55 }
     56 
     57 void build(int l,int r,int n)
     58 {
     59     int mid=(l+r)/2;
     60     f[n].l=l;
     61     f[n].r=r;
     62     f[n].len=f[n].r-f[n].l+1;
     63     if(l==r)
     64     {
     65         f[n].lnum=Date[l];
     66         f[n].rnum=Date[l];
     67         f[n].lmax=f[n].rmax=f[n].max=1;
     68         return ;
     69     }
     70     build(l,mid,n*2);
     71     build(mid+1,r,n*2+1);
     72     make_up(&f[n],&f[n*2],&f[n*2+1]);
     73 }
     74 
     75 int query(int l,int r,int n)
     76 {
     77     int mid=(f[n].l+f[n].r)/2,cur=0,now1=0,now2=0;
     78 
     79     if(f[n].l==l && f[n].r==r)
     80     {
     81         return f[n].max;
     82     }
     83     if(mid>=r)
     84     cur=query(l,r,n*2);
     85     else if(mid<l)
     86     cur=query(l,r,n*2+1);
     87     else
     88     {
     89         now1=query(l,mid,n*2);
     90         now2=query(mid+1,r,n*2+1);
     91         if(f[n*2].rnum==f[n*2+1].lnum)
     92         {
     93             cur=hmax(hmax(now1,now2),hmin(mid-l+1,f[n*2].rmax)+
     94                      hmin(r-mid,f[n*2+1].lmax));
     95         }
     96         else
     97         {
     98             cur=hmax(now1,now2);
     99         }
    100     }
    101     return cur;
    102 }
    103 
    104 void make_ini(int Q)
    105 {
    106     int l,r;
    107     while(Q--)
    108     {
    109         scanf("%d%d",&l,&r);
    110         printf("%d
    ",query(l,r,1));
    111     }
    112 }
    113 
    114 int main()
    115 {
    116     int N,Q,i;
    117     while(scanf("%d",&N)>0)
    118     {
    119         if(N==0)break;
    120         scanf("%d",&Q);
    121         for(i=1;i<=N;i++)
    122         scanf("%d",&Date[i]);
    123         build(1,N,1);
    124         make_ini(Q);
    125     }
    126 }
    View Code

    1006

     1 /*
     2 求区间[l,r],最大值和最小值的差值。
     3 */
     4 
     5 
     6 #include<iostream>
     7 #include<cstdio>
     8 #include<cstdlib>
     9 #include<cstring>
    10 #include<algorithm>
    11 #define MAX 1000010
    12 using namespace std;
    13 
    14 
    15 struct node
    16 {
    17     int l;
    18     int r;
    19     int min;
    20     int max;
    21 }f[50003*4];
    22 int Date[50003];
    23 
    24 
    25 int hmax(int x,int y)
    26 {
    27     return x>y? x:y;
    28 }
    29 
    30 int hmin(int x,int y)
    31 {
    32     return x>y? y:x;
    33 }
    34 
    35 void build(int l,int r,int n)
    36 {
    37     int mid=(l+r)/2;
    38     f[n].l=l;
    39     f[n].r=r;
    40     if(l==r)
    41     {
    42         f[n].max=Date[l];
    43         f[n].min=Date[l];
    44         return;
    45     }
    46     build(l,mid,n*2);
    47     build(mid+1,r,n*2+1);
    48     f[n].max=hmax(f[n*2].max,f[n*2+1].max);
    49     f[n].min=hmin(f[n*2].min,f[n*2+1].min);
    50 }
    51 
    52 void query(int l,int r,int *a,int *b,int n)
    53 {
    54     int mid=(f[n].l+f[n].r)/2;
    55     if(f[n].l==l && f[n].r==r)
    56     {
    57         if(f[n].min<*a)
    58         *a=f[n].min;
    59         if(f[n].max>*b)
    60         *b=f[n].max;
    61         return;
    62     }
    63     if(mid>=r)
    64     query(l,r,a,b,n*2);
    65     else if(mid<l)
    66     query(l,r,a,b,n*2+1);
    67     else
    68     {
    69         query(l,mid,a,b,n*2);
    70         query(mid+1,r,a,b,n*2+1);
    71     }
    72 }
    73 
    74 int main()
    75 {
    76     int N,Q,i;
    77     int a,b,l,r;
    78     while(scanf("%d%d",&N,&Q)>0)
    79     {
    80         for(i=1;i<=N;i++)
    81         scanf("%d",&Date[i]);
    82         build(1,N,1);
    83         while(Q--)
    84         {
    85             scanf("%d%d",&l,&r);
    86             a=MAX;b=-1;
    87             query(l,r,&a,&b,1);
    88             printf("%d
    ",b-a);
    89         }
    90     }
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    安装mysql
    date, Calendar
    心态
    jdbc ---- DBUTilDao 类
    jdbc--------JdbcUtilDao 类
    Python与C/C++相互调用
    用链表和数组实现HASH表,几种碰撞冲突解决方法
    用链表实现消息队列
    文件系统的发展
    [深度学习]开源的深度学习框架
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3236453.html
Copyright © 2011-2022 走看看