假定有一个无限长的数轴,数轴上每一个坐标上的数都是0。code
如今,咱们首先进行 n 次操做,每次操做将某一位置x上的数加c。xml
接下来,进行 m 次询问,每一个询问包含两个整数l和r,你须要求出在区间[l, r]之间的全部数的和。blog
输入格式
第一行包含两个整数n和m。get
接下来 n 行,每行包含两个整数x和c。it
再接下里 m 行,每行包含两个整数l和r。io
输出格式
共m行,每行输出一个询问中所求的区间内数字和。
数据范围
−10^9≤x≤10^9 −10^9≤x≤10^9,
1≤n,m≤10^5 1≤n,m≤10^5,
−10^9≤l≤r≤10^9 −10^9≤l≤r≤10^9,
−10000≤c≤10000 −10000≤c≤10000
输入样例:
3 3 1 2 3 6 7 5 1 3 4 6 7 8
输出样例:
8 0 5
分析:数的范围很大,可是个数却很少,能够用一个数组来存。
代码以下:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int N=3e5+10; 5 int n,m,q[N]; 6 struct node{ 7 int id,x; 8 }s[N],e[N]; 9 bool cmp(node a,node b) 10 { 11 return a.id<b.id; 12 } 13 int er1(int x)//二分查左端点 14 { 15 int l=1,r=n+2*m,mid; 16 while(l<r) 17 { 18 mid=l+r>>1; 19 if(s[mid].id>=x) 20 r=mid; 21 else 22 l=mid+1; 23 } 24 return l; 25 } 26 int er2(int x)//二分查右端点 27 { 28 int l=1,r=n+2*m,mid; 29 while(l<r) 30 { 31 mid=l+r+1>>1; 32 if(s[mid].id<=x) 33 l=mid; 34 else 35 r=mid-1; 36 } 37 return l; 38 } 39 int main() 40 { 41 int k=0; 42 scanf("%d%d",&n,&m); 43 for(int i=1;i<=n;i++) scanf("%d%d",&s[i].id,&s[i].x); 44 for(int i=n+1;i<=n+2*m;i++) 45 { 46 int l,r; 47 scanf("%d%d",&l,&r); 48 s[i].id=l;s[i].x=0; 49 i++; 50 s[i].id=r;s[i].x=0; 51 e[k].id=l;e[k].x=r; 52 k++; 53 } 54 sort(s+1,s+n+2*m+1,cmp); 55 for(int i=1;i<=n+2*m;i++) q[i]=q[i-1]+s[i].x; 56 for(int i=0;i<k;i++) 57 { 58 //printf("%d %d\n",e[i].id,e[i].x); 59 int l=er1(e[i].id); 60 int r=er2(e[i].x); 61 //printf("%d %d\n",l,r); 62 printf("%d\n",q[r]-q[l-1]); 63 } 64 return 0; 65 }