• 【CODEVS1080】线段树练习


    Description

    一行N个方格,开始每个格子里都有一个整数。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和;修改的规则是指定某一个格子x,加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N<100000,,提问和修改的总数m<10000条。

    Input

    输入文件第一行为一个整数N,接下来是n行n个整数,表示格子中原来的整数。接下一个正整数m,再接下来有m行,表示m个询问,第一个整数表示询问代号,询问代号1表示增加,后面的两个数x和A表示给位置X上的数值增加A,询问代号2表示区间求和,后面两个整数表示a和b,表示要求[a,b]之间的区间和。

    Output

    共m行,每个整数

    Sample Input

    6

    3

    4

    1 3 5

    2 1 4

    1 1 9

    2 2 6

    Sample Output

    22

    22

    HINT

    1≤N≤100000, m≤10000 。

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 const int maxn=100010;
     5 int tot=0;
     6 int a[100005];
     7 struct treetype
     8 {
     9     int Left,Right; //区间[Left,Right)
    10     int lptr,rptr; //左右孩子指针
    11     int sum; //区间和
    12 }t[2*maxn];
    13 void buildtree(int ll,int rr) //建树
    14 {
    15     int cur=++tot; //线段树中结点总个数
    16     t[cur].Left=ll; 
    17     t[cur].Right=rr;
    18     if(ll!=rr-1)//非单位区间
    19     {
    20         t[cur].lptr=tot+1;
    21         buildtree(ll,(ll+rr)/2);
    22         t[cur].rptr=tot+1;
    23         buildtree((ll+rr)/2,rr);
    24         t[cur].sum=t[t[cur].lptr].sum+t[t[cur].rptr].sum;
    25     }else t[cur].sum=a[ll];
    26 }
    27 void change(int k,int p,int delta) //修改单个元素的值,根节点作为第一个参数传入(k)
    28 {
    29     if(t[k].Left==t[k].Right-1) t[k].sum+=delta;
    30     else
    31     {
    32         if (p<(t[k].Left+t[k].Right)/2)
    33             change(t[k].lptr,p,delta);
    34         if (p>=(t[k].Left+t[k].Right)/2)
    35             change(t[k].rptr,p,delta);
    36         t[k].sum=t[t[k].lptr].sum+t[t[k].rptr].sum;
    37     }
    38 }
    39 int query(int k,int ll,int rr) //查询[ll,rr)区间和,根节点作为第一个参数传入(k)
    40 {
    41     if (ll<=t[k].Left&&rr>=t[k].Right) return t[k].sum;  //区间覆盖树
    42     int ans=0;
    43     if (ll<(t[k].Left+t[k].Right)/2) ans+=query(t[k].lptr,ll,rr);
    44     if (rr>(t[k].Left+t[k].Right)/2) ans+=query(t[k].rptr,ll,rr);
    45     return ans;
    46 }
    47 int main()
    48 {
    49     int n;
    50     scanf("%d",&n);
    51     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    52     buildtree(1,n+1);
    53     cin>>n;
    54     int p,at,x;
    55     for (int i=1;i<=n;i++)
    56     {
    57         cin>>at>>x>>p;
    58         if (at==1) change(1,x,p);
    59         if (at==2) printf("%d
    ",query(1,x,p+1));
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    谷歌控制台的使用
    等比例居中
    display:block、inline、inline-block的区别及应用案例
    省市县三级联动逻辑
    页面滑动至某处,固定导航。
    类加载器在Tomcat中的应用
    MySQL中一些关于索引的知识点
    Spring中AOP相关源码解析
    Spring中Bean的实例化与DI的过程
    我该如何学习spring源码以及解析bean定义的注册
  • 原文地址:https://www.cnblogs.com/liumengyue/p/5097169.html
Copyright © 2020-2023  润新知