zoukankan      html  css  js  c++  java
  • P3368 【模板】树状数组 2(区间增减,单点查询)

     P3368 【模板】树状数组 2

    题目描述

    如题,已知一个数列,你需要进行下面两种操作:

    1.将某区间每一个数数加上x

    2.求出某一个数的和

    输入输出格式

    输入格式:

    第一行包含两个整数N、M,分别表示该数列数字的个数和操作的总个数。

    第二行包含N个用空格分隔的整数,其中第i个数字表示数列第i项的初始值。

    接下来M行每行包含2或4个整数,表示一个操作,具体如下:

    操作1: 格式:1 x y k 含义:将区间[x,y]内每个数加上k

    操作2: 格式:2 x 含义:输出第x个数的值

    输出格式:

    输出包含若干行整数,即为所有操作2的结果。

    输入输出样例

    输入样例#1:
    5 5
    1 5 4 2 3
    1 2 4 2
    2 3
    1 1 5 -1
    1 3 5 7
    2 4
    输出样例#1:
    6
    10

    说明

    时空限制:1000ms,128M

    数据规模:

    对于30%的数据:N<=8,M<=10

    对于70%的数据:N<=10000,M<=10000

    对于100%的数据:N<=500000,M<=500000

    样例说明:

    故输出结果为6、10

     1 #include<iostream>
     2 using namespace std;
     3 
     4 const int N = 500100 ;
     5 
     6 int n,m,a;
     7 int ch,x,y,v;
     8 int sum[N];//树状数组 
     9 
    10 int lowbit(int x)         
    11 {
    12     return x&(-x);
    13 }
    14 
    15 void update(int p,int v)    //将第P个数增加v 
    16 {
    17     while(p<=n)
    18     {
    19         sum[p] += v;
    20         p += lowbit(p);
    21     }    
    22 } 
    23 
    24 int query(int p)    //查询第p个点的值是多少 
    25 {
    26     int ans=0;
    27     while(p)
    28     {
    29         ans += sum[p];
    30         p -= lowbit(p);
    31     }
    32     return ans;
    33 }
    34 
    35 int main()
    36 {
    37     ios::sync_with_stdio(false) ; 
    38     cin>>n>>m;
    39     int last=0;
    40     for (int i=1;i<=n;i++) 
    41     {
    42         cin>>a;
    43         update(i,a-last);  //建树 
    44         last = a;
    45     /*    
    46         这里运用了差分思想,假设原本的数据存在a数组中,
    47         那么c数组储存的就是c[i]=a[i]-a[i-1],如果c[1]=a[1],那么很明显
    48         a[i]=c[i]+c[i-1]+c[i-2]+...+c[2]+c[1].
    49         这样我们每次单点查询的时候只要加上c数组的前缀就可以了。
    50     */
    51     }
    52     for (int i=1;i<=m;++i) 
    53     {
    54         cin>>ch;
    55         if (ch==1)        //区间修改 
    56         {
    57             cin>>x>>y>>v;
    58             update(x,v);
    59               update(y+1,-v); 
    60         }
    61         if (ch==2)        //单点查询 
    62         {
    63             cin>>x;            
    64             cout<<query(x)<<endl; 
    65         }
    66     }
    67     return 0;
    68 }

    更新模板

     1 #include<cstdio>
     2 int sum[500100];
     3 int n,m,last = 0;
     4 
     5 void update(int p,int v) {
     6     for (; p<=n; p+=p&(-p)) sum[p] += v;
     7 }
     8 int query(int p) {
     9     int ans = 0;
    10     for (; p; p-=p&(-p)) ans += sum[p];
    11     return ans;
    12 }
    13 
    14 int main()
    15 {
    16     scanf("%d%d",&n,&m);
    17     for (int a,i=1; i<=n; ++i)
    18     {
    19         scanf("%d",&a);
    20         update(i,a-last);
    21         last = a;
    22     }
    23     for (int x,y,z,a,i=1; i<=m; ++i)
    24     {
    25         scanf("%d",&a);
    26         if (a==1)    //区间修改
    27         {
    28             scanf("%d%d%d",&x,&y,&z);
    29             update(x,z);
    30             update(y+1,-z); 
    31         } 
    32         else        //单点查询 
    33         {
    34             scanf("%d",&x);
    35             printf("%d
    ",query(x));
    36         }
    37     }
    38     return 0;
    39 }
  • 相关阅读:
    HTML页面空格记录&nbsp;&ensp; &emsp; (小计)
    JS对象、构造器函数和原型对象之间的关系
    情人节,送女友一桶代码可否?
    JavaScript中的BOM和DOM
    js中字符替换函数String.replace()使用技巧
    XML DOM 节点类型(Node Types)
    node 基础
    npm脚本命令npm run script的使用
    Node.js学习笔记六,获取get/post请求的参数
    querystring模块详解
  • 原文地址:https://www.cnblogs.com/mjtcn/p/6831402.html
Copyright © 2011-2022 走看看