zoukankan      html  css  js  c++  java
  • 线段树模板

    基础线段树模板:

     1 #include<iostream>
     2 #include<string.h>
     3 #include<stdio.h>
     4 using namespace std;
     5 
     6 const int maxn=200005;
     7 
     8 int val[maxn+1];
     9 
    10 struct node
    11 {
    12     int max;//需要处理的值
    13     int left;
    14     int right;
    15 }tree[maxn*3];//开三倍就够了
    16 
    17 int get_max(int x,int y)
    18 {
    19     if(x>y)
    20     return x;
    21     else
    22     return y;
    23 }
    24 
    25 int creat(int Root,int Left,int Right)//根节点和根节点的左右区间
    26 {
    27     tree[Root].left=Left;
    28     tree[Root].right=Right;//对每个节点定义其左右节点
    29     
    30     if(Left==Right)//子叶
    31     return tree[Root].max=val[Left];//返回的是需要处理值  也就是递归调用的边界
    32     
    33     int a,b,mid=(Left+Right)>>1;
    34     
    35     a=creat(Root<<1,Left,mid);
    36     b=creat((Root<<1)+1,mid+1,Right);
    37     
    38     return tree[Root].max=get_max(a,b);//向上一层递归返回该节点的处理值
    39     
    40     //这样,一个节点的最基本元素,1、节点所拥有的区间 2、节点的处理值
    41 }
    42 
    43 int calculate(int Root,int Left,int Right)
    44 {
    45     if(tree[Root].left>Right||tree[Root].right<Left)
    46     return 0;//没有交集,直接返回一个不会影响结果的无关值
    47     
    48     if(Left<=tree[Root].left&&tree[Root].right<=Right)
    49     return tree[Root].max;//该区间搞好为所求区间的一个子集,可直接返回该区间的处理值
    50     
    51     int a,b;
    52     a=calculate(Root<<1,Left,Right);
    53     b=calculate((Root<<1)+1,Left,Right);
    54     return get_max(a,b);//向上一层返回得到的处理值
    55 }
    56 
    57 int update(int Root,int pos,int value)//更新表面上看起来只是更新一个点,实际是更新的该店的所有的父节点
    58 {
    59     if(pos<tree[Root].left||tree[Root].right<pos)
    60     return tree[Root].max;//与索要更新的点(区间)没有交集,忽略更新
    61     
    62     if(tree[Root].left==pos&&tree[Root].right==pos)
    63     return tree[Root].max=value;//刚好就是给点
    64     
    65     int a,b;
    66     a=update(Root<<1,pos,value);
    67     b=update((Root<<1)+1,pos,value);
    68     
    69     return tree[Root].max=get_max(a,b);//更新该节点的最新处理值
    70 }
    71 
    72 int main()
    73 {
    74     int n,m;
    75     //freopen("aa.txt","r",stdin);
    76     while(scanf("%d %d",&n,&m)!=EOF)
    77     {
    78         for(int i=1;i<=n;i++)
    79         {
    80             scanf("%d",&val[i]);
    81         }
    82         creat(1,1,n);
    83         char s;
    84         int a,b;
    85         while(m--)
    86         {
    87             getchar();
    88             scanf("%c",&s);
    89             scanf("%d %d",&a,&b);
    90             if(s=='U')
    91             update(1,a,b);
    92             else
    93             printf("%d
    ",calculate(1,a,b));
    94         }
    95     }
    96     return 0;
    97 }
    View Code

     更新区间值模板(将某个区间全部更新为一个值)

    代码:

      1 #include<iostream>
      2 #include<string.h>
      3 #include<stdio.h>
      4 using namespace std;
      5 
      6 const int maxn=100005;
      7 
      8 //int val[maxn+1];
      9 
     10 struct node
     11 {
     12     int mark;
     13     int total;//需要处理的值
     14     int left;
     15     int right;
     16 }tree[maxn*3];//开三倍就够了
     17 
     18 int creat(int Root,int Left,int Right)//根节点和根节点的左右区间
     19 {
     20     tree[Root].mark=0;//未标记
     21     tree[Root].left=Left;
     22     tree[Root].right=Right;//对每个节点定义其左右节点
     23 
     24     if(Left==Right)//子叶
     25     return tree[Root].total=1/*val[Left]*/;//返回的是需要处理值  也就是递归调用的边界
     26 
     27     int a,b,mid=(Left+Right)>>1;
     28 
     29     a=creat(Root<<1,Left,mid);
     30     b=creat((Root<<1)+1,mid+1,Right);
     31 
     32     return tree[Root].total=a+b;//向上一层递归返回该节点的处理值
     33 
     34     //这样,一个节点的最基本元素,1、节点所拥有的区间 2、节点的处理值
     35 }
     36 
     37 void update_mark(int root)
     38 {
     39     if(tree[root].mark)
     40     {
     41         tree[root].total=tree[root].mark*(tree[root].right-tree[root].left+1);//更新该节点的实际值
     42         if(tree[root].left!=tree[root].right)//还存在左右孩子
     43         {
     44             tree[root<<1].mark=tree[root].mark;
     45             tree[root<<1|1].mark=tree[root].mark;
     46         }
     47         tree[root].mark=0;
     48     }
     49 }
     50 
     51 int calculate(int Root,int Left,int Right)
     52 {
     53     update_mark(Root);
     54     if(tree[Root].left>Right||tree[Root].right<Left)
     55     return tree[Root].total;//没有交集,直接返回一个不会影响结果的无关值
     56 
     57     if(Left<=tree[Root].left&&tree[Root].right<=Right){
     58         return tree[Root].total;//该区间搞好为所求区间的一个子集,可直接返回该区间的处理值
     59     }
     60     int a,b;
     61     a=calculate(Root<<1,Left,Right);
     62     b=calculate((Root<<1)+1,Left,Right);
     63     return a+b;//向上一层返回得到的处理值
     64 }
     65 
     66 int update(int Root,int left,int right,int value)//更新表面上看起来只是更新一个点,实际是更新的该店的所有的父节点
     67 {
     68     update_mark(Root);
     69     if(tree[Root].left>right||tree[Root].right<left)
     70     return tree[Root].total;//与索要更新的点(区间)没有交集,忽略更新
     71 
     72     if(tree[Root].left>=left&&tree[Root].right<=right){
     73         tree[Root].mark=value;
     74         return tree[Root].total=tree[Root].mark*(tree[Root].right-tree[Root].left+1);
     75     }
     76     int a,b;
     77     a=update(Root<<1,left,right,value);
     78     b=update((Root<<1)+1,left,right,value);
     79 
     80     return tree[Root].total=a+b;//更新该节点的最新处理值
     81 }
     82 
     83 int main()
     84 {
     85     int t;
     86     //freopen("aa.txt","r",stdin);
     87     scanf("%d",&t);
     88 
     89     for(int kase=1;kase<=t;kase++)
     90     {
     91         int n,m;
     92         scanf("%d %d",&n,&m);
     93         creat(1,1,n);
     94         int a,b,c;
     95         while(m--)
     96         {
     97             scanf("%d %d %d",&a,&b,&c);
     98             update(1,a,b,c);
     99         }
    100         printf("Case %d: The total value of the hook is %d.
    ",kase,calculate(1,1,n));
    101     }
    102     return 0;
    103 }
    View Code
  • 相关阅读:
    类加载机制的学习4___类加载的过程
    类加载机制的学习3___自定义的类加载器
    类加载机制的学习2_____双亲委派模型
    使用.NET读取exchange邮件
    SSMS错误:A connection was successfully established with the server, but then an error occurred during the login process
    收缩数据库 DBCC SHRINKFILE
    How to: Change Sales Rep/Team via Mass Update
    Microsoft.Office.Interop.Word.Document.Open returns null on Windows Server 2008 R2
    设置文件夹的权限
    NetSuite API
  • 原文地址:https://www.cnblogs.com/zhanzhao/p/3612231.html
Copyright © 2011-2022 走看看