1. 程式人生 > >利用差分實現的樹狀陣列區間修改 區間求和

利用差分實現的樹狀陣列區間修改 區間求和

最開始和很不敢相信竟然樹狀陣列還可以區間修改,既然常數這麼小,而且好寫易調的樹狀陣列可以寫區間修改了,那豈不美滋滋?

所以我在網上查了查做法,竟然學會了???
Orz http://blog.csdn.net/qq_21841245/article/details/43956633
這篇部落格給了我很大幫助
然後我們可以這樣思考,如果現在是區間修改,單點查詢,那麼我們是不是可以差分一下,在區間的開始和結束進行差分標記,然後用樹狀陣列維護差分陣列的字首和即可,然後詢問的時候只需要詢問到到這個點的差分陣列的字首和再加上這個點的值就可以吧
那麼如果是區間修改區間查詢呢?我們仍然維護字首和,也是差分陣列的字首和,不過維護的方式有一些變化,我們進行如下的公式推導

sum[i]=j=1ia[j]+delta[1]i+delta[2](i1)+...+delta[i]1
=j=1ia[j]+j=1idelta[j](ij+1)
=j=1ia[j]+j=1idelta[j]j=1idelta[j]j
所以我們只需要維護後面的兩個式子就行了,分別用兩個樹狀陣列維護delta[x]的字首和和delta[x]*x的字首和,而前面的那個式子我們可以預處理出來
所以我也寫了那位博主的那道題,果然奇快233
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath> #include<algorithm> #include<vector> #include<map> #include<queue> #include<set> const int MAXN=200000*4; using namespace std; int lowbit(int x){return x&(-x);} int n,Q,opt,x,y; long long A[MAXN],C[MAXN],sum[MAXN],z; void modifyA(int x,int val){ while
(x<=n){ A[x]+=val; x+=lowbit(x); } } void modifyC(int x,long long val){ while(x<=n){ C[x]+=val; x+=lowbit(x); } } void update(int from,int to,long long val){ modifyA(from,val); modifyA(to+1,-val); modifyC(from,val*from); modifyC(to+1,-val*(to+1)); } long long queryA(int loc){ long long ans=0; while(loc){ ans+=A[loc]; loc-=lowbit(loc); } return ans; } long long queryC(int loc){ long long ans=0; while(loc){ ans+=C[loc]; loc-=lowbit(loc); } return ans; } long long query(int loc){ return sum[loc]+(loc+1)*queryA(loc)-queryC(loc); } long long query(int from,int to){ return query(to)-query(from-1); } int main(){ scanf("%d",&n); for(register int i=1;i<=n;i++)scanf("%d",&sum[i]),sum[i]+=sum[i-1]; scanf("%d",&Q); while(Q--){ scanf("%d%d%d",&opt,&x,&y); if(opt==1){ scanf("%lld",&z); update(x,y,z); }else{ printf("%lld\n",query(x,y)); } } return 0; }

這裡寫圖片描述

相關推薦

利用實現陣列區間修改 區間求和

最開始和很不敢相信竟然樹狀陣列還可以區間修改,既然常數這麼小,而且好寫易調的樹狀陣列可以寫區間修改了,那豈不美滋滋? 所以我在網上查了查做法,竟然學會了??? Orz http://blog.c

ACM-ICPC 2018 瀋陽賽區網路預賽 J. Ka Chang (塊+陣列+dfs序)

題意 給你一顆樹,由兩種操作: 1.把這棵樹深度為 D D D的點全部都加上一個值。 2.求以p為根節點的子樹的權值和是多少? 思路 對於樹上的東西,我們可以把他求一下DFS序,之後就可以把樹上的結構變成

REQ 【CodeForces - 594D】【陣列+離線查詢+區間思維】

題目連結   很好的一道題,昨晚上推的,今天由於程式碼能力太弱敲了半天,再不斷的找到自己思維的BUG,於是RE了一發、T了一發、WA了一發,就Ac了,還不錯,那我們來講解一下題目的思路。   我們知道對於一個值的尤拉函式值,就是它的值去乘上它所有的質數-1除以質數:如

ACM-ICPC 2018 瀋陽賽區網路預賽 J. Ka Chang (塊+陣列+dfs序)

題意 給你一顆樹,由兩種操作: 1.把這棵樹深度為DD的點全部都加上一個值。 2.求以p為根節點的子樹的權值和是多少? 思路 對於樹上的東西,我們可以把他求一下DFS序,之後就可以把樹上的結構變成線性的結構,之後就是查詢和修改這兩個東西了。 關於修改

Educational Codeforces Round 56 (Rated for Div. 2) E. Intersection of Permutations(塊 + 陣列

題目連結:https://codeforces.com/contest/1093/problem/E 題目大意:給出兩個1~n的排列 a 和 b;對這兩個排列進行如下兩種操作: 1 la ra lb rb:查詢排列 a 的區間 [la,ra]

1057 Stack (30 陣列求堆疊中位數

題目 Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations inc

SPOJ D-query 陣列離線 求區間內不同數字的個數

Given a sequence of n numbers a1, a2, …, an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j)

[BZOJ4889][Tjoi2017]不勤勞的圖書管理員-塊-陣列

不勤勞的圖書管理員 Description 加里敦大學有個帝國圖書館,小豆是圖書館閱覽室的一個書籍管理員。他的任務是把書排成有序的,所以無序的書讓他產生厭煩,兩本亂序的書會讓小豆產生這兩本書頁數的和的厭煩度。現在有n本被打亂順序的書,在接下來m天中每天都會因

20140719 「陣列 - 區間更新,區間求和」 POJ 3468 A Simple Problem with Integers

Language: A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 58536 Accepted: 17827 Case Time

矩陣陣列(矩陣加矩陣求和)

將矩陣分為很多由lowbit 組成的小矩陣 , 然後就跟樹狀陣列一樣維護了 求和的時候用矩陣字首和的思想(s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1])  單點修改時將(x1,y1)加 , (x2+1,y2) 減 , (x1,

陣列---區間更新(陣列實現

/* * @Author: Achan * @Date: 2018-10-28 12:55:01 * @Last Modified by: Achan * @Last Modified time: 2018-10-28 19:59:13 */ #incl

陣列區間加法(

應用差分原理,實現樹狀陣列區間加法 差分:a區間[1, 2, 3, 4, 5],則差分割槽間為[1, 1, 1, 1, 1]即bn = an - an-1,an = b1 +…+ bn 如果對區間[2, 4]都加上2,則a[1, 5, 6, 7, 5], 差分割槽間[1, 4, 1,

陣列專題 (單點更新、區間求和) + (區間更新、單點查詢) + (區間更新、區間求和)(思想)

                                                                                            樹狀陣列專題 一直感覺樹狀陣列用處比較小而且侷限、因為最基本的用法就是單點更新和區間求和、

陣列 區間修改

傳送門 // by spli #include<cstring> #include<cstdio> #include<algorithm> #include<iostream> using namespace s

陣列區間更新)思想

已知一個數列,你需要進行下面兩種操作: 1.將某區間每一個數數加上x 2.求出某一個數的和 題: 第一行包含兩個整數N、M,分別表示該數列數字的個數和操作的總個數。 第二行包含N個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。 接下來M行每行包含2或

牛客網 小白賽5 I區間 線段思想,陣列

分析:這個題目一看,恩,好像就是區間修改查詢,馬上想到了線段樹,一毛一樣,但是線段樹的時間複雜度為O(nlogn),可能會卡時間,但是題目稍鬆的話不會卡,但是空間要開四倍,所以說很可能空間不夠用,關鍵是題目資料太多,就要開long long ,然後我就只過了百分之三十的資

【模板】陣列

題目描述 如題,已知一個數列,你需要進行下面兩種操作: 1.將某區間每一個數數加上x 2.求出某一個數的和 輸入輸出格式 輸入格式: 第一行包含兩個整數N、M,分別表示該數列數字的個數和操作的總個數。 第二行包含N個用空格分隔的整數,其中第i個數字表示數列第i項的初始值

HDU——1556 【陣列&&陣列】Color the ball

  N個氣球排成一排,從左到右依次編號為1,2,3....N.每次給定2個整數a b(a <= b),lele便為騎上他的“小飛鴿"牌電動車從氣球a開始到氣球b依次給每個氣球塗一次顏色。但是N次以後lele已經忘記了第I個氣球已經塗過幾次顏色了,你能幫他算出每個氣球被塗過幾次顏色

藍書(演算法競賽進階指南)刷題記錄——POJ3468 A Simple Problem with Intergers(陣列維護

題目:poj3468. 題目大意:給定一個序列a,要求支援: 1.格式C a b c,表示將[a,b]的權值都加上c. 2.格式Q a b,表示查詢[a,b]的權值和. 線段樹裸題(我像個傻子一樣寫了個LCT做了一遍),可是我們這裡不用線段樹,我們討論樹狀陣列的解法. 我們已

洛谷P3368 陣列2 模板題 陣列+

戳我! 正解:樹狀陣列+差分 解題報告: 不得不說靈巧真滴是越來越弱了...連模板題都要放上來了QAQ 因為今天考試的T3正解要用到樹狀陣列這才警覺樹狀陣列掌握得太太太太差了...之前一直靠線段樹續著一條狗命然後又感覺挺複雜的就一直沒了解也懶得去理解QAQ 然後趕緊就滾去把兩個模板給做了 1就懶