題目給出範圍很大但資料數量很少的一組資料,通過離散化將大的下標的值賦值給新的較小的連續的下標,從而講乙個範圍很大的資料合集裝進乙個小的容器中。
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 新增操...