離散化

這裏只說一下離散化的簡單思路(還不會難的(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 }
相關文章
相關標籤/搜索