【离散化】 区间和

传送门

题意

一个无限长数轴,初始数轴上每个坐标上的数都是\(0\)

  • \(n\)个操作,每个操作将数轴某一位置上的数加\(c\)
  • \(m\)个询问,询问区间\([ l , r ]\)上所有数的和

数据范围

\(\begin{array}{l}-10^{9} \leq x \leq 10^{9} \\ 1 \leq n, m \leq 10^{5} \\ -10^{9} \leq l \leq r \leq 10^{9} \\ -10000 \leq c \leq 10000\end{array}\)

题解

坐标的范围是所有涉及到的点个数的\(10^{3}\)倍左右,只需要对涉及到的坐标按序离散化后操作即可
离散化后进行对应的操作通过二分找到离散化后的坐标,所以时间复杂度为\(O(N·logN)\)

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define fi first
#define se second
#define pb push_back
const int N = 3e5+10;
int a[N], sum[N];
int n, m;
typedef pair<int,int>pii;
vector <int> alls;
vector<pii>add,query;
int get(int x) {
    return lower_bound(alls.begin(), alls.end(), x) - alls.begin() + 1;
}
int main() {
    cin>>n>>m;
    rep(i, 0, n) {
        int x, c; cin>>x>>c;
        alls.pb(x); add.pb({x,c});
    }
    rep(i, 0, m) {
        int l, r; cin>>l>>r;
        query.pb({l, r}); alls.pb(l), alls.pb(r);
    }
    
    sort(alls.begin(), alls.end());
    unique(alls.begin(), alls.end());

    for(auto it : add) {
        int idx = get(it.fi);
        a[idx] += it.se;
    }
    rep(i, 1, alls.size() + 1) sum[i] = sum[i - 1] + a[i];
    for(auto it : query) {
        int l = get(it.fi), r = get(it.se);
        printf("%d\n", sum[r] - sum[l - 1]);
    }
    return 0;
}    
posted @ 2020-07-12 00:16  Hyx'  阅读(253)  评论(0编辑  收藏  举报