码迷,mamicode.com
首页 > 其他好文 > 详细

【离散化】 区间和

时间:2020-07-12 00:53:14      阅读:85      评论:0      收藏:0      [点我收藏+]

标签:problem   span   define   print   line   add   its   push   return   

题意

传送门
一个无限长数轴,初始数轴上每个坐标上的数都是\(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 vector<int> vi;
typedef pair<int,int>pii;
vi alls;
vector<pii>add,query;
int find_idx(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 r+1;
}
int main(){
    scanf("%d%d",&n,&m);
    rep(i,0,n){
        int x,c;
        scanf("%d%d",&x,&c);
        alls.pb(x);
        add.pb({x,c});
    }
    rep(i,0,m){
        int l,r;
        scanf("%d%d",&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=find_idx(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=find_idx(it.fi),r=find_idx(it.se);
        printf("%d\n",sum[r]-sum[l-1]);
    }
    return 0;
}   

【离散化】 区间和

标签:problem   span   define   print   line   add   its   push   return   

原文地址:https://www.cnblogs.com/hhyx/p/13286279.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!