楼房重建 线段树

~~~题面~~~

题解:

一栋楼是否已经被前面的楼房遮挡住,可以利用斜率来判断。

因此将原序列转化为斜率。

然后直接用线段树维护一下每个区间最多能看见多少楼房即可。

在更新区间的时候需要在线段树上二分,因为左区间是肯定可以取的,然后设左区间的最大值为k,

那么右区间的贡献就是大于k的最长上升子序列,二分即可。

建议画画图,还是很好理解的。

注意:这里其实并不是维护的传统意义上的最长递增子序列,因为这里的子序列强制从第一个开始了,所以代码中的注释其实有点问题,,(算法是对的)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define R register int
 4 #define AC 100100
 5 #define ac 600000
 6 int n, m;
 7 int tree[ac], l[ac], r[ac];//维护最长上升子序列和
 8 double mx[ac];
 9 
10 inline int read()
11 {
12     int x = 0;char c = getchar();
13     while(c > '9' || c < '0') c = getchar();
14     while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
15     return x;
16 }
17 
18 int cal(int x, double k)//当前点,大于k的最长上升子序列
19 {//计算在一段区间内大于k的可以被看见的有多少个
20     if(l[x] == r[x]) return mx[x] > k;
21     if(mx[x] <= k) return 0;
22     if(mx[x * 2] < k) return cal(x * 2 + 1, k);
23     else return tree[x] - tree[x * 2] + cal(x * 2, k);
24 }
25 
26 void update(int x)
27 {
28     mx[x] = max(mx[x * 2], mx[x * 2 + 1]);
29     tree[x] = tree[x * 2] + cal(x * 2 + 1, mx[x * 2]);
30 }
31 
32 void build(int x, int ll, int rr)
33 {
34     l[x] = ll, r[x] = rr;
35     if(ll == rr) return ;
36     int mid = (ll + rr) >> 1;
37     build(x * 2, ll, mid);
38     build(x * 2 + 1, mid + 1, rr);
39 }
40 
41 void change(int x, int w, double t)//当前点,目标点, 改成什么
42 {//单点修改并维护新值
43     if(l[x] == r[x])
44     {
45         mx[x] = t;
46         tree[x] = 1;
47         return ;
48     }
49     int mid = (l[x] + r[x]) >> 1;
50     if(w <= mid) change(x * 2, w, t);
51     else change(x * 2 + 1, w, t); 
52     update(x);
53 }
54 
55 void pre()
56 {
57     n = read(), m = read();
58     build(1, 1, n);
59 }
60 
61 void work()
62 {
63     int a, b;
64     for(R i = 1; i <= m; i ++)
65     {
66         a = read(), b = read();
67         change(1, a, (double)b / (double)a);//这个也要用double
68         printf("%d\n", tree[1]);
69     }
70 }
71 
72 int main()
73 {
74 //    freopen("in.in", "r", stdin);
75     pre();
76     work();
77 //    fclose(stdin);
78     return 0;
79 }
View Code

 

posted @ 2018-09-04 13:48  ww3113306  阅读(190)  评论(0编辑  收藏  举报
知识共享许可协议
本作品采用知识共享署名-非商业性使用-禁止演绎 3.0 未本地化版本许可协议进行许可。