HDU - 3308 LCIS 單點更新區間查詢
阿新 • • 發佈:2018-11-02
題解: 單點更新 區間查詢 分別儲存左連續 右連續 區間最大值 區間左右端點的大小 合併的時候判斷大小關係即可
Given n integers.
You have two operations:
U A B: replace the Ath number by B. (index counting from 0)
Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b].
Input
T in the first line, indicating the case number.
Each case starts with two integers n , m(0<n,m<=10 5).
The next line has n integers(0<=val<=10 5).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=10 5)
OR
Q A B(0<=A<=B< n).
Output
For each Q, output the answer.
Sample Input
1
10 10
7 7 3 3 5 9 9 8 1 8
Q 6 6
U 3 4
Q 0 1
Q 0 5
Q 4 7
Q 3 5
Q 0 2
Q 4 6
U 6 10
Q 0 9
Sample Output
1
1
4
2
3
1
2
5
#include<iostream> #include<algorithm> #include<cstdio> #include<cmath> #include<cstring> using namespace std; typedef long long ll; const int maxn=1e5+10; int n,m; struct node { int l,r; int ml,mr,mx; int numl,numr; }tree[maxn<<2]; void pushup(int cur) { tree[cur].numl=tree[cur*2].numl; tree[cur].numr=tree[cur*2+1].numr; tree[cur].mx=max(tree[cur*2].mx,tree[cur*2+1].mx); if(tree[cur*2].numr<tree[cur*2+1].numl) tree[cur].mx=max(tree[cur].mx,tree[cur*2].mr+tree[cur*2+1].ml); tree[cur].ml=tree[cur*2].ml; if(tree[cur].ml==tree[cur*2].r-tree[cur*2].l+1&&tree[cur*2].numr<tree[cur*2+1].numl) tree[cur].ml+=tree[cur*2+1].ml; tree[cur].mr=tree[cur*2+1].mr; if(tree[cur].mr==tree[cur*2+1].r-tree[cur*2+1].l+1&&tree[cur*2].numr<tree[cur*2+1].numl) tree[cur].mr+=tree[cur*2].mr; } void build(int l,int r,int cur) { tree[cur].l=l; tree[cur].r=r; if(r==l) { scanf("%d",&tree[cur].numl); tree[cur].numr=tree[cur].numl; tree[cur].ml=tree[cur].mr=tree[cur].mx=1; return; } int mid=(r+l)>>1; build(l,mid,cur<<1); build(mid+1,r,cur<<1|1); pushup(cur); //printf("%d-%d %d \n",tree[cur].l,tree[cur].r,tree[cur].mx); } int query(int pl,int pr,int cur) { if(pl<=tree[cur].l&&tree[cur].r<= pr) { return tree[cur].mx; } int res=0; if(pl<=tree[cur*2].r) res=max(res,query(pl,pr,cur*2)); if(pr>=tree[cur*2+1].l) res=max(res,query(pl,pr,cur*2+1)); if(pl<=tree[cur*2].r&&pr>=tree[cur*2+1].l&&tree[cur*2].numr<tree[cur*2+1].numl)// res=max(res,min(tree[cur*2].mr,tree[cur*2].r-pl+1)+min(tree[cur*2+1].ml,pr-tree[cur*2+1].l+1)); return res; } void update(int cur,int tar,int x) { if(tree[cur].l==tree[cur].r) { tree[cur].numl=tree[cur].numr=x; return; } if(tar<=tree[cur*2].r) update(cur<<1,tar ,x); else update(cur<<1|1,tar ,x); pushup(cur); } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); build(0,n-1,1); while(m--) { char op[2]; int l,r; int tar,x; scanf("%s",op); if(op[0]=='Q') { scanf("%d%d",&l,&r); printf("%d\n",query(l,r,1)); } else { scanf("%d%d",&tar,&x); update(1,tar,x); } } } return 0; }