zoukankan      html  css  js  c++  java
  • HDU1754 && HDU1166 线段树模板题

    HDU1754

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754

    题目分析:对于给出的一个很长的区间,对其进行单点更新值和区间求最大值的操作,由于查询的区间很大,且查询次数多,这里用线段树求解将是十分合适的

    注意点:1.对于存放线段树的数组大小需要开大一些

        2.对于c语言的字符输入%c之前需要加一个空格保证输入准确

     1 #include<iostream>
     2 #include<string.h>
     3 using namespace std;
     4 
     5 const int N = 200005;
     6 int grade[N];
     7 int tree[N<<2];                    //这里建立的树的数组大小需要是N的4倍 否则不够用 
     8 int n, m;
     9 
    10 int max(int a, int b){
    11     if(a > b) return a;
    12     else return b;
    13 }
    14 
    15 void build_tree(int start, int end, int node){                    //线段树的建立 
    16     if(start == end){
    17         tree[node] = grade[start];
    18     }else{
    19         int mid = (start + end) / 2;
    20         int left_node = node*2;
    21         int right_node = node*2+1;
    22         
    23         build_tree(start, mid, left_node);
    24         build_tree(mid+1, end, right_node);
    25         tree[node] = max(tree[left_node], tree[right_node]);
    26     }
    27 }
    28 
    29 void update_tree(int start, int end, int node, int index, int value){    //单点更新值 
    30     if(start == end){
    31         tree[node] = value;
    32     }else{
    33         int mid = (start + end) / 2;
    34         int left_node = node*2;
    35         int right_node = node*2+1;
    36         
    37         if(index <= mid)
    38             update_tree(start, mid, left_node, index, value);
    39         else
    40             update_tree(mid+1, end, right_node, index, value);
    41         tree[node] = max(tree[left_node], tree[right_node]);
    42     }
    43 }
    44 
    45 int search_tree(int start, int end, int node, int l, int r){        //区间查询最大值 
    46     if(l > end || r < start){
    47         return 0;
    48     }else if(l <= start && r >= end){
    49         return tree[node];
    50     }else if(start == end){      //这里的个递归出口放在后面是有原因的,有可能存在start==end 但是l和r根本和start end没有交集的情况,所以先判去了后者
    51         return tree[node];
    52     }
    53     int mid = (start + end) / 2;
    54     int left_node = node*2;
    55     int right_node = node*2+1;
    56     
    57     int left_max = search_tree(start, mid, left_node, l, r);
    58     int right_max = search_tree(mid+1, end, right_node, l, r);
    59     int ans = max(left_max, right_max);
    60     return ans;
    61 }
    62 
    63 int main(){
    64     while(scanf("%d%d", &n, &m) != EOF){
    65         for(int i = 1; i <= n; i++)
    66             scanf("%d", &grade[i]);
    67         build_tree(1, n, 1);    
    68         for(int i = 1; i <= m; i++){
    69             char c;
    70             int a, b;
    71             scanf(" %c %d %d", &c, &a, &b);            //对于c语言的输入字符在%c之前需要一个空格,否则c就读取不到需要的字符了 
    72             if(c == 'U') update_tree(1, n, 1, a, b);
    73             else{
    74                 int ans = search_tree(1, n, 1, a, b);
    75                 printf("%d
    ", ans);
    76             }
    77         }
    78     }    
    79     return 0;
    80 }

    HDU1166

    题目分析:

    也是一题线段树的模板题,单点更新和区间查询求和(本质上和区间求最大值是一样的)

    代码:

     1 #include<iostream>
     2 #include<string>
     3 #include<string.h>
     4 using namespace std;
     5 
     6 const int N = 500005;
     7 int peo[N];
     8 int tree[N<<2];
     9 
    10 void build_tree(int start, int end, int node){
    11     if(start == end){
    12         tree[node] = peo[start];
    13     }else{
    14         int mid = (start + end) / 2;
    15         int left_node = node*2;
    16         int right_node = node*2+1;
    17         
    18         build_tree(start, mid, left_node);
    19         build_tree(mid+1, end, right_node);
    20         tree[node] = tree[left_node] + tree[right_node];
    21     }
    22 }
    23 
    24 void update_tree(int start, int end, int node, int index, int value){
    25     if(start == end){
    26         tree[node] += value;
    27     }else{
    28         int mid = (start + end) / 2;
    29         int left_node = node*2;
    30         int right_node = node*2+1;
    31         
    32         if(index <= mid)
    33             update_tree(start, mid, left_node, index, value);
    34         else
    35             update_tree(mid+1, end, right_node, index, value);
    36         tree[node] = tree[left_node] + tree[right_node];    
    37     }
    38 }
    39 
    40 int query_tree(int start, int end, int node, int l, int r){
    41     if(end < l || start > r){
    42         return 0;
    43     }else if(start >= l && end <= r){
    44         return tree[node];
    45     }else if(start == end){
    46         return tree[node];
    47     }
    48     int mid = (start + end)    / 2;
    49     int left_node = node*2;
    50     int right_node = node*2+1;
    51     
    52     int left_sum = query_tree(start, mid, left_node, l, r);
    53     int right_sum = query_tree(mid+1, end, right_node, l, r);
    54     int ans = left_sum + right_sum;
    55     return ans;
    56 }
    57 
    58 int main(){
    59     int t;
    60     scanf("%d", &t);
    61     int cnt = 1;
    62     while(t--){
    63         printf("Case %d:
    ", cnt++);
    64         int n;
    65         scanf("%d", &n);
    66         for(int i = 1; i <= n; i++)
    67             scanf("%d", &peo[i]);
    68         build_tree(1, n, 1);
    69         string s;
    70         int a, b;
    71         while(cin>>s){
    72             if(s == "End") break;
    73             scanf("%d%d", &a, &b);
    74             if(s == "Query"){
    75                 int ans = query_tree(1, n, 1, a, b);    
    76                 printf("%d
    ", ans);
    77             }
    78             if(s == "Add"){
    79                 update_tree(1, n, 1, a, b);
    80             }
    81             if(s == "Sub"){
    82                 update_tree(1, n, 1, a, -b);
    83             }
    84         }
    85     }
    86     return 0;
    87 } 
  • 相关阅读:
    使用MobaXterm远程连接Ubuntu,启动Octave,界面不能正常显示
    ABP .Net Core 日志组件集成使用NLog
    ABP .Net Core Entity Framework迁移使用MySql数据库
    ABP前端使用阿里云angular2 UI框架NG-ZORRO分享
    阿里云 Angular 2 UI框架 NG-ZORRO介绍
    Visual Studio 2019 Window Form 本地打包发布猫腻
    VS Code + NWJS(Node-Webkit)0.14.7 + SQLite3 + Angular6 构建跨平台桌面应用
    ABP .Net Core 调用异步方法抛异常A second operation started on this context before a previous asynchronous operation completed
    ABP .Net Core To Json序列化配置
    .Net EF Core数据库使用SQL server 2008 R2分页报错How to avoid the “Incorrect syntax near 'OFFSET'. Invalid usage of the option NEXT in the FETCH statement.”
  • 原文地址:https://www.cnblogs.com/YLTFY1998/p/11811802.html
Copyright © 2011-2022 走看看