• 树状数组基本操作入门


    树状数组 2 :区间修改,单点查询
    给定数列a[1],a[2],…,a[n],你需要依次进行 q 个操作,
    操作有两类:
    1 l r x:给定 l,r,x对于所有 i∈[l,r]
    ,将 a[i]加上 x(换言之,将a[l],a[l+1],…,a[r]分别加上 x);
    2 i:给定 i,求 a[i]的值。

    输入
    第一行包含 2 个正整数 n,q表示数列长度和询问个数。保证 1≤n,q≤10^6
    第二行 n 个整数a[1],a[2],…,a[n],表示初始数列。保证 ∣a[i]∣≤10^6
    接下来 q 行,每行一个操作,为以下两种之一:
    1 l r x:对于所有 i∈[l,r],将 a[i]加上 x;
    2 i:给定 i,求 a[i]的值。
    保证 1≤l≤r≤n,∣x∣≤10^6

    输出
    对于每个 2 i 操作,输出一行,每行有一个整数,表示所求的结果。

    样例
    输入复制
    3 2
    1 2 3
    1 1 3 0
    2 2
    输出复制
    2

    #include<bits/stdc++.h>
    #define N 1000005
    #define ll long long
    #define lowbit(x) x&(-x)
    using namespace std;
    ll read(ll &x){
    ll dat=0,oko=1;char chc=getchar();
    while(chc<'0'||chc>'9'){if(chc=='-')oko=-1;chc=getchar();}
    while(chc<='9'&&chc>='0'){dat=dat*10+chc-'0';chc=getchar();}
    x=dat*oko;return x;
    }ll n,m,a[N],b[N],t,x,y,z,opt;
    void add(ll x,ll k)
    {
    while(k<=n)
    {
    a[k]+=x;
    k+=lowbit(k);
    }
    }ll ask(ll k)
    {
    ll ans=0;
    while(k>0){
    ans+=a[k];
    k-=lowbit(k);
    }return ans;
    }
    int main()
    {
      read(n),read(m);
      for(ll i=1;i<=n;i++)
      {
             read(b[i]);
      }  
      for(ll i=1;i<=m;i++)
      {
            read(opt),read(x);
            if(opt==1)
    		   {
    		         read(y),read(z);
    				 add(-z,y+1),add(z,x);
    				 //在x这个位置打上标记z,在y+1打上标记-z 
    		   }
            if(opt==2)printf("%lld
    ",b[x]+ask(x));
      }  
      return 0;
    }
    

      

    树状数组 3 :区间修改,区间查询
    1.给[a ,b]整体上加上一个常数c。
    2.查询[a ,b]区间的和。

    输入
    The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
    The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
    Each of the next Q lines represents an operation.
    "C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
    "Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

    输出
    You need to answer all Q commands in order. One answer in a line. The sums may exceed the range of 32-bit integers

    样例
    输入复制
    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 4 4
    Q 1 10
    Q 2 4
    C 3 6 3
    Q 2 4
    输出复制
    4
    55
    9
    15

     

    注意在维护i*B[i]时,可设exdel(i)=i*b[i]

    当我们在区间[L,R]加上V时

    exdel(L)=exdel(L)+V*L

    exdel(R+1)=exdel(R+1)-V*(R+1)

    于是我们按这种方式维护C1数组就好了。

    #include<iostream>
    long long s[100010],n,m;
    struct node{
    long long c[100010];
    void add(long long x,long long y)
    {
    for(;x<=n;x+=x&-x)c[x]+=y;
    }
    long long ask(long long x)
    {
    long long ans=0;
    for(;x;x-=x&-x)ans+=c[x];
    return ans;
    }
    }c1,c2;
    int main()
    {
    scanf("%lld%lld",&n,&m);
    for(int i=1;i<=n;i++)
    {
    scanf("%lld",s+i);
    s[i]+=s[i-1];
    }
    for(int i=1;i<=m;i++)
    {
    char k[3];
    long long a,b,c;
    scanf("%s",k);
    if(k[0]=='Q')
    {
    scanf("%lld%lld",&a,&b);
    printf("%lld
    ",s[b]+(b+1)*c1.ask(b)-c2.ask(b)-s[a-1]-a*c1.ask(a-1)+c2.ask(a-1));
    }
    else
    {
    scanf("%lld%lld%lld",&a,&b,&c);
    c1.add(a,c),c1.add(b+1,-c);
    c2.add(a,a*c),c2.add(b+1,-(b+1)*c);
    }
    }
    }
    

      

  • 相关阅读:
    随机获取Mysql数据表的一条或多条记录
    swap 释放
    linux sed
    mongodb url
    mysql doc
    mysql 8.0 主从复制的优化
    innobackupex 远程备份
    MySQL 8.0新特性:彻底解决困扰运维的复制延迟问题
    pycharm 激活码及使用方式
    MySQL运行内存不足时应采取的措施?
  • 原文地址:https://www.cnblogs.com/cutemush/p/14234464.html
Copyright © 2020-2023  润新知