區間和(離散化 二分 字首和)

2021-10-03 03:53:43 字數 1661 閱讀 3030

假定有乙個無限長的數軸,數軸上每個座標上的數都是0。

現在,我們首先進行 n 次操作,每次操作將某一位置x上的數加c。

近下來,進行 m 次詢問,每個詢問包含兩個整數l和r,你需要求出在區間[l, r]之間的所有數的和。

輸入格式

第一行包含兩個整數n和m。

接下來 n 行,每行包含兩個整數x和c。

再接下裡 m 行,每行包含兩個整數l和r。

輸出格式

共m行,每行輸出乙個詢問中所求的區間內數字和。

資料範圍

−109≤x≤109,

1≤n,m≤105,

−109≤l≤r≤109,

−10000≤c≤10000

由於題目給出的資料範圍太大,所以我們需要使用離散化。即將每乙個數對映到乙個自然數上。

離散化的核心**為:

sort

(alls.

begin()

,alls.

end())

;//先將區間排序

alls.

erase

(unique

(alls.

begin()

,alls.

end())

,alls.

end())

;//然後再去重

由於對區間進行了排序,所以區間具有單調性,這個時候就可以使用二分查詢來快速找到某乙個值所對應的下標,然後再求字首和即可。

#include

#include

#include

using

namespace std;

const

int maxn=3*

1e5+7;

typedef pair<

int,

int> pii;

vector<

int> alls;

vector add,query;

int n,m;

int a[maxn]

,s[maxn]

;//二分查詢,在alls中尋找離散後的數

intfind

(int x)

return r+1;

}// add用來儲存執行的操作,query用來儲存查詢的區間

intmain()

);}for

(int i=

0;i;}

//離散化

sort

(alls.

begin()

,alls.

end())

; alls.

erase

(unique

(alls.

begin()

,alls.

end())

,alls.

end())

;//執行相加的操作

for(

auto item:add)

//求字首和

for(

int i=

1;i<=alls.

size()

;i++

) s[i]

=s[i-1]

+a[i]

;for

(auto item:query)

}

離散化系列 離散化 字首和 差分

區間和 acwing 802.區間和 這道題所展現的情況就是,資料並不是很多,利用到的元素值也不大,但關鍵就是下標太大,無法正常的以陣列下標來進行操作。因此,離散化,在這裡就是很合適了,把大的下標對映為小的下標後再進行處理。對於這道題的解題步驟具體可分為一下幾步 1.儲存,就是將所用用到的下標存起來...

字首和 二分

powered by ab in 局外人 拿洛谷的乙個例子記一下字首和。資料超過了1e5,故o n 2 的演算法又行不通,所以換二分 include typedef long long ll using namespace std ll n,m,l,r ll a 1000001 sum 100000...

字首和 離散化

現在正在上課,但我還是要同步更新博文。滑稽 先講乙個離散化,就是把幾個離的特別遠的數在不影響結果的情況下,變成相近的數。倒是沒什麼影響,但應用在陣列下標的話可以節約空間。貌似和hash有點像 直接拍 給定n個數,如果乙個數出現x次,則對答案的貢獻為x 2 求這n個數對答案的貢獻是多少。n 10000...