AcWing 802. 区间和

匿名 (未验证) 提交于 2019-12-02 23:47:01

(https://www.acwing.com/problem/content/804/)

假定有一个无限长的数轴,数轴上每个坐标上的数都是0。

现在,我们首先进行 n 次操作,每次操作将某一位置x上的数加c。

近下来,进行 m 次询问,每个询问包含两个整数l和r,你需要求出在区间[l, r]之间的所有数的和。

输入格式

第一行包含两个整数n和m。

接下来 n 行,每行包含两个整数x和c。

再接下里 m 行,每行包含两个整数l和r。

输出格式

共m行,每行输出一个询问中所求的区间内数字和。

数据范围

109x109
1n,m1051≤n,m≤105,
109lr109
10000c10000

输入样例:

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

输出样例:

8 0 5思路:离散化+前缀和由于坐标的数据范围很大,那么将坐标离散化。排序去重后的新下标就是坐标离散化后的坐标。
#include <iostream> #include<algorithm> #include<vector> using namespace std; const int maxn = 3e5+10; typedef pair<int,int> pll; int a[maxn]; int s[maxn]; vector<pll> add,qu; vector<int> adds; int find1(int x) {     int l=0,r=adds.size()-1;     while(l<r)     {         int mid=l+r >> 1;         if(adds[mid]>=x) r=mid;         else l=mid+1;     }     return r+1; } int main() {     std::ios::sync_with_stdio(false);     int n,m;     cin >> n >> m;     for(int i=1;i<=n;i++)     {         int x,y;         cin >> x >> y;         add.push_back({x,y});         adds.push_back(x);     }     for(int i=1;i<=m;i++)     {         int l,r;         cin >> l >> r;         qu.push_back({l,r});         adds.push_back(l);         adds.push_back(r);     }     sort(adds.begin(),adds.end());     adds.erase(unique(adds.begin(),adds.end()),adds.end());     for(auto i : add)     {         int x=find1(i.first);         a[x]+=i.second;     }     for(int i=1;i<=adds.size();i++)     {         s[i]=s[i-1]+a[i];     }     for(auto j : qu)     {         int l=find1(j.first),r=find1(j.second);         cout << s[r]-s[l-1] << endl;     }     return 0; }

 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!