You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
typedef pair < int , int > PII ;
const int N = 300010 ; // 上限, n+2*m+10
int a [ N ] ; // 映射后的数组
int s [ N ] ; // a数组的前缀和数组
vector < int > alls ; // 坐标集合
vector < PII > add ; // 1、哪个位置, 2: 加上多少
vector < PII > query ; // 1、开始点, 2:结束点
int n , m ;
/**
* 功能: 利用二分法查找原索引x的映射后索引值
* 核心思路:原来是第几个是不变的,离散化后还是第几个,建立起了映射关系。
* @param x 原来的索引号
* @return 映射后小数组内的索引号
*/
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 l ;
}
// 883 ms
int main ( ) {
// 输入数据
cin > > n > > m ;
// 录入原始数据
while ( n - - ) {
int x , c ;
cin > > x > > c ;
// 记录位置与值
add . push_back ( { x , c } ) ;
// 将位置记录到alls里
alls . push_back ( x ) ;
}
// 读入查询范围
int l , r ;
while ( m - - ) {
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 ( ) ) ;
// 生成a数组, 每次都在映射后的坐标位置将值变大c
for ( int i = 0 ; i < add . size ( ) ; i + + ) {
PII item = add [ i ] ;
// find返回的是下标从0开始的位置, 这里为了使用前缀和, 要求a数据下标从1开始, 有1个偏移量
int x = find ( item . first ) + 1 ; // 映射为小范围的索引值
a [ x ] + = item . second ;
}
// 预处理前缀和
for ( int i = 1 ; i < N ; i + + ) s [ i ] = s [ i - 1 ] + a [ i ] ;
// 处理询问(前缀和应用)
for ( int i = 0 ; i < query . size ( ) ; i + + ) {
PII item = query [ i ] ;
// 根据原来的位置值,计算出映射后的位置值
l = find ( item . first ) + 1 ;
r = find ( item . second ) + 1 ;
// 利用一维前缀和计算区间和
cout < < s [ r ] - s [ l - 1 ] < < endl ;
}
return 0 ;
}