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
1 1 4 2 3 1 2 5
题目大意:给一串数字,1种操作,将第a个数改成b;一种查询,查询区间[a,b]的LICS。
题目分析:跟这种题一个类型,同时维护端点左右连续值就可以了。详情请见代码:
#include <iostream> #include<cstdio> #include<cstring> using namespace std; const int N = 100005; struct node { int lc,rc;//区间左右LCIS int lv,rv;//区间左右端点值 int ans;//区间LCIS }tree[N<<2]; int m,n; int Max(int a,int b) { return a > b?a:b; } int Min(int a,int b) { return a > b?b:a; } void pushup(int num,int s,int e) { int ls = num<<1; int rs = num<<1|1; int mid = (s + e)>>1; tree[num].lv = tree[ls].lv; tree[num].rv = tree[rs].rv; tree[num].lc = tree[ls].lc; if(tree[ls].ans == mid - s + 1 && tree[ls].rv < tree[rs].lv) tree[num].lc += tree[rs].lc; tree[num].rc = tree[rs].rc; if(tree[rs].ans == e - mid && tree[rs].lv > tree[ls].rv) tree[num].rc += tree[ls].rc; int cmp = Max(tree[ls].rc,tree[rs].lc); if(tree[ls].rv < tree[rs].lv) cmp = tree[ls].rc + tree[rs].lc; tree[num].ans = Max(tree[ls].ans,Max(tree[rs].ans,cmp)); } void build(int num,int s,int e) { if(s == e) { scanf("%d",&tree[num].lv); tree[num].rv = tree[num].lv; tree[num].lc = tree[num].rc = 1; tree[num].ans = 1; return; } int mid = (s + e)>>1; build(num<<1,s,mid); build(num<<1|1,mid + 1,e); pushup(num,s,e); } void update(int num,int s,int e,int pos,int val) { if(s == e) { tree[num].lv = tree[num].rv = val; return; } int mid = (s + e)>>1; if(pos <= mid) update(num<<1,s,mid,pos,val); else update(num<<1|1,mid + 1,e,pos,val); pushup(num,s,e); } int query(int num,int s,int e,int l,int r) { if(s == l && r == e) { return tree[num].ans; } int mid = (s + e)>>1; if(r <= mid) return query(num<<1,s,mid,l,r); else { if(l > mid) return query(num<<1|1,mid + 1,e,l,r); else { int ta = Min(tree[num<<1].rc,mid - l + 1); int tb = Min(tree[num<<1|1].lc,r - mid); int middle = Max(ta,tb); if(tree[num<<1].rv < tree[num<<1|1].lv) middle = ta + tb; return Max(query(num<<1,s,mid,l,mid),Max(query(num<<1|1,mid + 1,e,mid + 1,r),middle)); } } } int main() { int t; char op[3]; int a,b; scanf("%d",&t); while(t --) { scanf("%d%d",&n,&m); build(1,1,n); while(m --) { scanf("%s",op); scanf("%d%d",&a,&b); if(op[0] == 'Q') printf("%d\n",query(1,1,n,a + 1,b + 1)); else update(1,1,n,a + 1,b); } } return 0; } //343MS 5376K