整数离散化 离散化的概念 对一组序列进行升序排列,然后用0映射,代表序列的最小数,1映射第二小的数,以此类推,与利用数组存储相似
如果序列中有重复元素,应当先去重删除重复元素再排序映射
对序列1 2 2 3 5离散化 排序得到1 2 2 3 5 去重并删除得到1 2 3 5 离散化映射 序列1 2 3 5 映射0 1 2 3
模板 int main () { vector<int > alls; sort (alls.begin (), alls.end ()); alls.erase (unique (alls.begin (), alls.end ()),alls.end ());
例题 1 #define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include <vector> #include <algorithm> using namespace std;int n,x;vector<int > alls; int find (int x) { int l = 0 , r = alls.size () - 1 ; while (l < r) { int mid = (l + r) >> 1 ; if (alls[mid] >= x) r = mid; else l = mid + 1 ; } return r; } int main () { cin >> n >> x; int number; for (int i = 0 ;i < n;++i) { cin >> number; alls.push_back (number); } sort (alls.begin (), alls.end ()); alls.erase (unique (alls.begin (), alls.end ()),alls.end ()); cout << find (x) << endl; return 0 ; }
例题2
假定有一个无限长的数轴,数轴上每个坐标上的数都是 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
输入样例:
输出样例:
题解
#define _CRT_SECURE_NO_WARNINGS 1 #include <iostream> #include <vector> #include <algorithm> using namespace std;typedef pair<int , int > PII;const int N = 300010 ;int n, m;int a[N], s[N];vector <int > alls; vector<PII> add, query; int find (int x) { int l = 0 , r = alls.size () - 1 ; while (l < r) { int mid = (l + r) >> 1 ; if (alls[mid] >= x) r = mid; else l = mid + 1 ; } return r + 1 ; } int main () { cin >> n >> m; for (int i = 0 ;i < n;++i) { int x, c; cin >> x >> c; add.push_back ({ x,c }); alls.push_back (x); } for (int i = 0 ;i < m;++i) { int l, r; cin >> l >> r; query.push_back ({l,r}); 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) { int x = find (item.first); a[x] += item.second; } 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); cout << s[r] - s[l - 1 ] << endl; } return 0 ; }