• 敌兵布阵


    hdu1166:http://acm.hdu.edu.cn/showproblem.php?pid=1166

    题意:n个阵营一字排开,每个初始有a[i]个人。现有两种操作:Q a b 查询[a,b]之间总人数并输出A/S a b 在a号位添加/删除b个人
    题解:用线段树维护,就是单点更新,区间查询。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<cstdio>
     5 using namespace std;
     6 int n,a,b;
     7 struct Node{
     8     int left;//左二子 
     9     int right;//右儿子 
    10     int sum;//一顶点为子树的和 
    11 }node1[50005*4];//这里一定要注意,是4倍的点,不然会越界,自己犯过错 
    12 void build(int l,int r,int idx){//建树 
    13      node1[idx].left=l;
    14      node1[idx].right=r;//注意这里,第一次,把这里弄丢了 
    15     if(l==r){
    16       scanf("%d",&node1[idx].sum);//到底就读取数据 
    17         return;
    18     }
    19     int midx=(l+r)>>1;
    20     build(l,midx,idx<<1);//向下建立子树 
    21     build(midx+1,r,(idx<<1)+1);
    22     node1[idx].sum=node1[idx<<1].sum+node1[(idx<<1)+1].sum;//建完子树,向上更新父亲节点的和 
    23 }
    24 int query(int s,int t,int idx){//区间查询 
    25     if(s==node1[idx].left && t==node1[idx].right){
    26         return node1[idx].sum;
    27     }
    28     int midx=(node1[idx].left+node1[idx].right)/2;//这里第一次忘记了/2,找了几个小时 
    29     if(midx>=t) return query(s,t,idx*2);//在左二子 
    30     else if(midx<s)return query(s,t,idx*2+1);//在右儿子 
    31     else {
    32         return (query(s,midx,idx*2)+query(midx+1,t,idx*2+1));//在中间 
    33     }
    34 } 
    35 void update(int p,int add,int l,int r,int idx ){//单点更新 
    36     if(node1[idx].left==node1[idx].right){
    37     node1[idx].sum+=add;
    38       return;
    39       }
    40      int midx=(r+l)/2;
    41      if(p<=midx)
    42        update(p,add,l,midx,idx*2);
    43      else 
    44       update(p,add,midx+1,r,idx*2+1);
    45      node1[idx].sum=node1[idx*2].sum+node1[idx*2+1].sum; //向上更新,不是+=,是=  
    46 }
    47 int main(){
    48     int cas;char ss[8];
    49     scanf("%d",&cas);
    50     int t=1;
    51     while(cas--){
    52         printf("Case %d:
    ",t++);
    53         scanf("%d",&n);
    54         build(1,n,1);
    55     while(~scanf("%s",ss)){
    56           if(ss[0]=='E')break;
    57           if(ss[0]=='Q'){
    58               scanf("%d%d",&a,&b);
    59               printf("%d
    ",query(a,b,1));
    60           }
    61          else if(ss[0]=='A'){
    62            scanf("%d%d",&a,&b);
    63            update(a,b,1,n,1);    
    64           } 
    65          else{
    66              scanf("%d%d",&a,&b);
    67            update(a,-b,1,n,1);    
    68          }
    69       }    
    70     }
    71 }
    View Code
  • 相关阅读:
    HashMap深度解析(二)(转)
    HashMap深度解析(一)(转)
    GeoHash核心原理解析(转)
    spring boot 策略模式实践
    Java中CAS详解(转)
    springMVC请求流程详解(转)
    7 vi 编辑器
    Linux 命令行快捷键
    Java
    3 Eclipse 查看不了源码
  • 原文地址:https://www.cnblogs.com/chujian123/p/3387942.html
Copyright © 2020-2023  润新知