假定有乙個無限長的數軸,數軸上每個座標上的數都是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...