基礎演算法學習 離散化

2022-07-19 07:06:18 字數 1601 閱讀 3621

題目給出範圍很大但資料數量很少的一組資料,通過離散化將大的下標的值賦值給新的較小的連續的下標,從而講乙個範圍很大的資料合集裝進乙個小的容器中。
vecrotalls; // 儲存所有待離散化的值

sort(alls.begin(),alls.end()); // 將alls裡的所有待離散化的值總小到大排序

alls.erase(unique(alls.begin(),alls.end()),alls.end()) // 將重複的待離散化資料刪除

//因為離散化是下標對下標的對映,不需要重複值。

int find(int x)

return r + 1; //這樣離散化對映的值是從1開始的

}

題目

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

現在,我們首先進行 nn 次操作,每次操作將某一位置 xx 上的數加 cc。

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

輸入格式

第一行包含兩個整數 nn 和 mm。

接下來 nn 行,每行包含兩個整數 xx 和 cc。

再接下來 mm 行,每行包含兩個整數 ll 和 rr。

輸出格式

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

資料範圍

−109≤x≤109−109≤x≤109,

1≤n,m≤1051≤n,m≤105,

−109≤l≤r≤109−109≤l≤r≤109,

−10000≤c≤10000

題解

#include#include#includeusing namespace std;

const int n = 300010;

typedef pairp;

int n,m;

int a[n],s[n];

vectoradd,query;

vectoralls;

int find(int x)

return r + 1;

}int main());

alls.push_back(x);

}while(m --));

alls.push_back(l);

alls.push_back(r);

}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){

int l = find(item.first),r = find(item.second);

coutalls.erase() 擦去指定部分

unique() 將所有重複的數放在最後面並返回end的值

演算法學習筆記 14 離散化操作

離散化是一種輔助解決問題的操作,當問題中涉及的資料範圍非常大,但是實際使用到的資料是比較少的。並且問題的求解是和它範圍裡的其它資料有關係的,那麼可以將這些可能使用到的資料放到一起,排序去重,就將它們對映到了乙個新的較小的範圍裡。例如,下面幾個數是在 infty,infty 範圍裡的,實際用到的數 6...

基礎演算法 離散化

離散化主要是通過建立乙個對映,將分散的元素的位置對映成連續的位置以節約空間。說明 x為題目要進行操作的陣列元素的下標,y為經過離散化後的下標。原理 若不離散化,則針對該例需要開乙個大小為9000000的陣列儲存操作結果!通過建立乙個對映陣列來儲存所有要進行操作的下標x,然後將其排序去重,每次操作x位...

基礎演算法6 離散化

問題引入 a i 1 3 100 2000 50000 對映到 0 1 2 3 4 解決問題1 a中可能重複元素 解決問題2 如何快速算出x離散化後的值 n個新增操作,m個詢問操作 int n,m a陣列存數,s陣列存字首和 int a n s n 所有會用到的元素下標 vectoralls 新增操...