[bzoj3155]Preprefix sum(树状数组)

3155: Preprefix sum

Time Limit: 1 Sec  Memory Limit: 512 MB
Submit: 1183  Solved: 546
[Submit][Status][Discuss]

Description

Input

第一行给出两个整数N,M。分别表示序列长度和操作个数

接下来一行有N个数,即给定的序列a1,a2,....an

接下来M行,每行对应一个操作,格式见题目描述

Output

对于每个询问操作,输出一行,表示所询问的SSi的值。

Sample Input

5 3
1 2 3 4 5
Query 5
Modify 3 2
Query 5

Sample Output

35
32

HINT

1<=N,M<=100000,且在任意时刻0<=Ai<=100000

Source

Katharon+#1

学过线段树都知道树状数组不能处理区间修改,无逆元的区间加法

但是树状数组其实用差分可以做区间修改单点查询

当然这道题和更强的区间修改求和关系不大,但形式确实很像

对于原数列a1,a2,a3,a4...

S为  1*a1, 1*a1+1*a2, 1*a1+1*a2+1*a3...

SS为1*a1, 2*a1+1*a2, 3*a1+2*a2+1*a3...

观察系数,发现从大到小变化,但序号却由小到大

比较一下,可以尝试把S乘一个i,消掉系数最大的

得到  1*a1, 2*a1+2*a2, 3*a1+3*a2+3*a3...

这样与SS作差,就可以又得到一个系数与序号正比的式子

0*a1, 0*a1+1*a2, 0*a1+1*a2+2*a3...

再观察,这就是个前缀和而已

所以维护一遍原前缀和,再维护(i-1)*a[i]的前缀和即可

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #define LL long long
 5 int n,m;
 6 LL a[101000],bit1[101000],bit2[101000];
 7 int lb(int x){
 8     return x&(-x);
 9 }
10 LL q1(int x){
11     LL ans=0;
12     while(x){
13         ans+=bit1[x];
14         x-=lb(x);
15     }
16     return ans;
17 }
18 LL q2(int x){
19     LL ans=0;
20     while(x){
21         ans+=bit2[x];
22         x-=lb(x);
23     }
24     return ans;
25 }
26 int c1(int x,LL num){
27     while(x<=n){
28         bit1[x]+=num;
29         x+=lb(x);
30     }
31     return 0;
32 }
33 int c2(int x,LL num){
34     while(x<=n){
35         bit2[x]+=num;
36         x+=lb(x);
37     }
38     return 0;
39 }
40 int main(){
41     scanf("%d %d",&n,&m);
42     for(int i=1;i<=n;i++){
43         scanf("%lld",&a[i]);
44         c1(i,a[i]);
45         c2(i,(i-1)*a[i]);
46     }
47     for(int i=1;i<=m;i++){
48         char in[10];
49         scanf("%s",in);
50         if(in[0]==‘Q‘){
51             int x;
52             scanf("%d",&x);
53             printf("%lld\n",x*q1(x)-q2(x));
54         }else{
55             int x;
56             LL y;
57             scanf("%d %lld",&x,&y);
58             LL tmp=y-a[x];
59             a[x]+=tmp;
60             c1(x,tmp);
61             c2(x,(x-1)*tmp);
62         }
63     }
64     return 0;
65 }

时间: 2024-08-09 10:43:48

[bzoj3155]Preprefix sum(树状数组)的相关文章

codeforces 703D D. Mishka and Interesting sum(树状数组)

题目链接: D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes input standard input output standard output Little Mishka enjoys programming. Since her birthday has just passed, her friends decided to present h

Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum 树状数组+离线

D. Mishka and Interesting sum time limit per test 3.5 seconds memory limit per test 256 megabytes input standard input output standard output Little Mishka enjoys programming. Since her birthday has just passed, her friends decided to present her wit

Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 树状数组

D. Mishka and Interesting sum 链接: http://codeforces.com/problemset/problem/703/D 题意: 给一个序列 每次询问一个区间 求区间中出现次数为偶数次的数的异或和 代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<map> 5 using namespace std; 6 7 str

hdu 2838 Cow Sorting 树状数组求所有比x小的数的个数

Cow Sorting Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4766    Accepted Submission(s): 1727 Problem Description Sherlock's N (1 ≤ N ≤ 100,000) cows are lined up to be milked in the evening.

hdu3015树状数组

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3015 题意:给定n组数,每组数有值x和值h,求n组数两两的val的总和.将所有x和所有h分别离散化(不去重)变成x'和h',val(i,j)为abs(x'i-x'j)*min(hi',hj'). 如: x,    h——>x',h' 10,100——>1,1 50,500——>4,4 20,200——>3,3 20,100——>1,1 思路:只要把n*n优化成n*logn就可以过

差分+树状数组【p4868】Preprefix sum

Description 前缀和(prefix sum)\(S_i=\sum_{k=1}^i a_i\). 前前缀和(preprefix sum) 则把\(S_i\)作为原序列再进行前缀和.记再次求得前缀和第i个是\(SS_i\) 给一个长度n的序列\(a_1, a_2, \cdots, a_n\)有两种操作: Modify i x:把\(a_i\)改成\(x\): Query i:查询\(SS_i\) Input 第一行给出两个整数N,M.分别表示序列长度和操作个数 接下来一行有N个数,即给定的

leetcode 307. Range Sum Query - Mutable(树状数组)

Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. The update(i, val) function modifies nums by updating the element at index i to val. Example: Given nums = [1, 3, 5] sumRange(0, 2) -> 9 update(1, 2

Leetcode——2 Range Sum Query - Mutable(树状数组实现)

Problem: Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive. The update(i, val) function modifies nums by updating the element at index i to val. Example: Given nums = [1, 3, 5] sumRange(0, 2) -> 9 up

CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)

转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有出现偶数次的数异或的值. 思路:容易想到,把区间内的所有的数都异或得到的是出现奇数次的数的值,然后再异或该区间内的所有出现过的数(每个数只统计一次),得到的ans了. 第一个问题:得到询问区间的