题解 P1198 【[JSOI2008]最大数】

说起来这还是蒟蒻AC的第一道省选线段树呢。

这道题和其他线段树最大的不同就是在于本题数组一直在增大。

寻常的线段树蒟蒻习惯用如下的结构体储存,然而对于此题就不行了:

1 struct node{
2     int l, r;
3     int val;
4 } tree[maxn << 2];

这是因为这道题没有用建树,因此l, r就不存在啊!

那么解决方法就是用朴实的tree数组储存val, l和r则手动传入函数!!

所以根据这个原理,稍微修改一下模板就可以得出全新的两个函数!!

 1 void Update(ll l, ll r, ll index, ll value, ll pos) {
 2     if(l == r) {
 3         tree[pos] = value;
 4         return ;
 5     }
 6     ll mid = (l + r) >> 1;
 7     if(mid >= index) Update(l, mid, index, value, pos << 1);
 8     if(mid < index) Update(mid + 1, r, index, value, pos << 1 | 1);
 9     tree[pos] = max(tree[pos << 1], tree[pos << 1 | 1]);
10 }
11 
12 ll Query(ll L, ll R, ll l, ll r, ll pos) {
13     if(L >= l && R <= r) return tree[pos];
14     ll mid = (L + R) >> 1;
15     ll ans = 0;
16     if(mid >= l) ans = max(ans, Query(L, mid, l, r, pos << 1));
17     if(mid < r) ans = max(ans, Query(mid + 1, R, l, r, pos << 1 | 1));
18     return ans;
19 }

注明:第二个函数中,L,R表示当前区间,l,r表示寻找的区间。

完整AC代码献上:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 typedef long long ll;
 7 const int maxn = 200200;
 8 
 9 ll tree[maxn << 2];
10 
11 ll m, d, t = 0, len = 0, x;
12 char op;
13 
14 void Update(ll l, ll r, ll index, ll value, ll pos) {
15     if(l == r) {
16         tree[pos] = value;
17         return ;
18     }
19     ll mid = (l + r) >> 1;
20     if(mid >= index) Update(l, mid, index, value, pos << 1);
21     if(mid < index) Update(mid + 1, r, index, value, pos << 1 | 1);
22     tree[pos] = max(tree[pos << 1], tree[pos << 1 | 1]);
23 }
24 
25 ll Query(ll L, ll R, ll l, ll r, ll pos) {
26     if(L >= l && R <= r) return tree[pos];
27     ll mid = (L + R) >> 1;
28     ll ans = 0;
29     if(mid >= l) ans = max(ans, Query(L, mid, l, r, pos << 1));
30     if(mid < r) ans = max(ans, Query(mid + 1, R, l, r, pos << 1 | 1));
31     return ans;
32 }
33 
34 int main() {
35     cin >> m >> d;
36     for(ll i = 0; i < m; i++){
37         cin >> op >> x;
38         if(op == 'Q') {
39             if(x == 0) {
40                 t = 0;
41                 cout << t << endl;
42             } else {
43                 t = Query(1, m, len - x + 1, len, 1);
44                 cout << t << endl;
45             }
46         } else {
47             len++;
48             Update(1, m, len, (x + t) % d, 1);
49         }
50     }
51 }

本代码1776ms, 氧化后1276ms。

比较玄学的一件事就是用cin过了,用scanf和快读却TLE了。【滑稽】

posted @ 2018-10-19 21:43  Ilverene  阅读(262)  评论(0编辑  收藏  举报