802. 區間和(離散化)

題目描述

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

輸入樣例:

3 3
1 2
3 6
7 5
1 3
4 6
7 8

輸出樣例:

8
0
5

思路:標準的離散化,給的數據和範圍很大,但總共也只有n個數,所以可以給這n這數就行重新編號。
代碼如下:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e6 + 10;
typedef long long ll;
typedef pair<int, int> p;
int a[N], sum[N];
p arr[N], query[N];
int n ,m;
vector<int>alls;   //重新編號
int Find(int x)     //查找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()
{
    int l ,r ;
    cin >>n >> m;
    for(int i = 0; i < n; i++){
        cin >> arr[i].first >> arr[i].second;
        alls.push_back(arr[i].first);
    }
    for(int i = 0; i < m; i++){
        cin >> l >> r;
        query[i].first = l;
        query[i].second = r;
        alls.push_back(l);
        alls.push_back(r);
    }
    //重新編號:去重和排序
    sort(alls.begin(), alls.end());
    alls.erase(unique(alls.begin(), alls.end()), alls.end());  
    for(int i = 0; i < n; i++){
        int x = Find(arr[i].first);
        a[x] += arr[i].second;
    }
    for(int i = 1; i <= alls.size(); i++)
        sum[i] = sum[i - 1] + a[i];
    for(int i = 0; i < m; i++){
        int l = Find(query[i].first);
        int r = Find(query[i].second);
        cout << sum[r] - sum[l - 1] << endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章