离散化

这里只说一下离散化的简单思路(还不会难的(T _ T))node

离散化的就是将大范围的缩小到小范围来表示,这类问题通常是数的范围很大,可是个数很少,数组

具体的思路是,将他们用一个数组来表示,查找其原位置时用二分查找便可。ui

一个模板题:区间和spa

 

假定有一个无限长的数轴,数轴上每一个坐标上的数都是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^9x10^9 −10^9≤x≤10^9,
1n,m10^1≤n,m≤10^5,
10^9lr10^−10^9≤l≤r≤10^9,
10000c10000  −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 }
相关文章
相关标签/搜索