更新一个点;
求某个区间的最长连续上升序列;
链接:http://acm.hdu.edu.cn/showproblem.php?pid=3308
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 #define maxn 100009 5 #define mid int m=(l+r)>>1 6 int num[maxn], lsum[maxn<<2], rsum[maxn<<2], msum[maxn<<2], n, m, p, v, a, b; 7 void pushup(int o, int l, int r) 8 { 9 mid; 10 if (num[m] < num[m+1]) 11 { 12 lsum[o] = (lsum[o<<1] == m+1-l) ? (m+1-l+lsum[o<<1|1]) : lsum[o<<1]; 13 rsum[o] = (rsum[o<<1|1] == r-m) ? (r-m+rsum[o<<1]) : rsum[o<<1|1]; 14 msum[o] = max(max(msum[o<<1], msum[o<<1|1]), lsum[o<<1|1] + rsum[o<<1]); 15 } 16 else lsum[o] = lsum[o<<1], rsum[o] = rsum[o<<1|1], msum[o] = max(msum[o<<1], msum[o<<1|1]); 17 } 18 void build(int o, int l, int r) 19 { 20 if (l == r) {lsum[o]= rsum[o] = msum[o] = 1; return;} 21 mid; build(o<<1, l, m), build(o<<1|1, m+1, r), pushup(o, l, r); 22 } 23 void update(int o, int l, int r) 24 { 25 if (l == r) {num[p] = v; return;} 26 mid; if (p <= m) update(o<<1, l, m); else update(o<<1|1, m+1, r); pushup(o, l, r); 27 } 28 int query(int o, int l, int r) 29 { 30 if (a <= l && b >= r) return msum[o]; 31 mid; int ret = 0; 32 if (a <= m) ret = max(ret, query(o<<1, l, m)); if (b > m) ret = max(ret, query(o<<1|1, m+1, r)); 33 if (num[m] < num[m+1]) ret = max(ret, min(m-a+1, rsum[o<<1])+min(b-m, lsum[o<<1|1])); return ret; 34 } 35 int main(void) 36 { 37 int t, n, m; char ch[5]; scanf("%d", &t); 38 while (t--) 39 { 40 scanf("%d%d", &n, &m); for (int i = 1; i <= n; scanf("%d", num+i++)); build(1, 1, n); 41 while (m--) 42 { 43 scanf("%s%d%d", ch, &a, &b); a++, b++; 44 if (ch[0] == 'Q') printf("%d\n", query(1, 1, n)); else p = a, v = b-1, update(1, 1, n); 45 } 46 } 47 return 0; 48 }
。。