题面
假定有一个无限长的数轴,数轴上每个坐标上的数都是0。
现在,我们首先进行 n 次操作,每次操作将某一位置x上的数加c。
近下来,进行 m 次询问,每个询问包含两个整数l和r,你需要求出在区间[l, r]之间的所有数的和。
输入格式
第一行包含两个整数n和m。
接下来 n 行,每行包含两个整数x和c。
再接下里 m 行,每行包含两个整数l和r。
输出格式
共m行,每行输出一个询问中所求的区间内数字和。
数据范围
−109≤x≤109−109≤x≤109,
1≤n,m≤1051≤n,m≤105,
−109≤l≤r≤109−109≤l≤r≤109,
−10000≤c≤10000−10000≤c≤10000
输入样例:
3 3
1 2
3 6
7 5
1 3
4 6
7 8
输出样例:
8
0
5
【题解】:
1.观察数据,发现数据给的很大,但是数量却没有很多,所以要进行离散化。
2.目前我对离散化的理解是:用一个vector去存下原来的数,而且要排序去重。之后要找这个值的话就可以写一个findd数组用二分去找。
3.排序和去重可以用STL来做:
(1)排序:sort(xxxx.begin(),xxxx.end())
(2)去重:用erase加上unique,erase就是给出两指针,删掉他们之间的所有的数;unique就是针对排好顺序的一组数(一般),把不重复的往前排,并且返回的是不重复的最后一个元素的后面一个位置。
4.这个题目的话,把加数和查询的位置存下来,之后去重排序,然后再实行加数的操作,完了之后求一下前缀和,之后的查询前缀和来完成就可。
二分的模板
顺便记录一下二分的模板(y神的模板):
算法思路:
假设目标值在闭区间[l, r]中, 每次将区间长度缩小一半,当l = r时,我们就找到了目标值。
版本1
当我们将区间[l, r]划分成[l, mid]和[mid + 1, r]时,其更新操作是r = mid或者l = mid + 1;,计算mid时不需要加1。
C++ 代码模板:
int bsearch_1(int l, int r)
{
while (l < r)
{
int mid = l + r >> 1;
if (check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
版本2
当我们将区间[l, r]划分成[l, mid - 1]和[mid, r]时,其更新操作是r = mid - 1或者l = mid;,此时为了防止死循环,计算mid时需要加1。
C++ 代码模板:
int bsearch_2(int l, int r)
{
while (l < r)
{
int mid = l + r + 1 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
return l;
}
作者:yxc
链接:https://www.acwing.com/blog/content/31/
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1000005;
typedef pair<int,int> p;
int a[maxn],sum[maxn];
p arr[maxn],qury[maxn];
vector<int> alls;
int findd(int x)
{
int l=0;
int 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;
int n,m;
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;
qury[i].first=l;
qury[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=findd(arr[i].first);
a[x]+=arr[i].second;
}
for(int i=1;i<=alls.size();i++)
{
sum[i]=sum[i-1]+a[i];
// cout<<" i="<<i<<" sum[i]="<<sum[i]<<endl;
}
for(int i=0;i<m;i++)
{
l=findd(qury[i].first);
r=findd(qury[i].second);
cout<<sum[r]-sum[l-1]<<endl;
}
return 0;
}