题目链接:http://acm.hdu.edu.cn/showproblem.php?
pid=3308
LCIS
Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5792 Accepted Submission(s): 2513
Problem Description
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].
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<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
OR
Q A B(0<=A<=B< n).
Each case starts with two integers n , m(0<n,m<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
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
Author
shǎ崽
Source
Recommend
题目大意:给n个数,m个操作。两种操作:Q a b 表示查询【a。b】这个区间的LCIS(即最长连续递增子序列)的长度。U a b 表示更新第a个数把他变成b(从0開始)。
解题思路:主要解决简单的单点更新和区间的查询,区间记录最长的连续递增子序列长度。要分析清楚各种情况。
详见代码。
#include <iostream> #include <cstdio> using namespace std; struct node { int l,r; int mmax; int lmax,rmax; int lnum,rnum; }s[100000*4+10]; void InitTree(int l,int r,int k) { s[k].l=l; s[k].r=r; s[k].mmax=1; s[k].rmax=1; s[k].lmax=1; s[k].lnum=s[k].rnum=0; if (l==r) return ; int mid=(l+r)/2; InitTree(l,mid,2*k); InitTree(mid+1,r,2*k+1); } void UpdataTree(int i,int change,int k) { if (s[k].l==s[k].r&&s[k].l==i) { s[k].lnum=s[k].rnum=change; return ; } int mid=(s[k].l+s[k].r)/2; if (i>mid) UpdataTree(i,change,2*k+1); else if (i<=mid) UpdataTree(i,change,2*k); s[k].lnum=s[k*2].lnum; s[k].rnum=s[k*2+1].rnum; s[k].lmax=s[k*2].lmax; s[k].rmax=s[k*2+1].rmax; s[k].mmax=max(s[k*2].mmax,s[k*2+1].mmax); if(s[k*2].rnum<s[k*2+1].lnum) { s[k].mmax=max(s[k].mmax,s[k*2].rmax+s[k*2+1].lmax); if(s[k*2].lmax==s[k*2].r-s[k*2].l+1) s[k].lmax=s[k*2].lmax+s[k*2+1].lmax; if(s[k*2+1].rmax==s[k*2+1].r-s[k*2+1].l+1) s[k].rmax=s[k*2].rmax+s[k*2+1].rmax; } } int SearchTree(int l,int r,int k) { if (s[k].l==l&&s[k].r==r) return s[k].mmax; else { int mid=(s[k].l+s[k].r)/2; if (l>mid) return SearchTree(l,r,2*k+1); else if (r<=mid) return SearchTree(l,r,2*k); /*else { if (s[k].lnum<s[k].rnum) return SearchTree(l,mid,2*k)+SearchTree(mid+1,r,2*k+1); else if }*/ else { int a=min(s[k*2].rmax,mid-l+1); int b=min(s[k*2+1].lmax,r-mid); int Max=max(a,b); Max=max(Max,SearchTree(l,mid,2*k)); Max=max(Max,SearchTree(mid+1,r,2*k+1)); if(s[k*2].rnum<s[2*k+1].lnum) { Max=max(Max,a+b); } return Max; } } } int main() { int t; char ch[70]; scanf("%d",&t); while (t--) { int n,m,w,a,b; scanf("%d%d",&n,&m); InitTree(0,n-1,1); for (int i=0; i<n; i++) { scanf("%d",&w); UpdataTree(i,w,1); } for (int i=0; i<m; i++) { //getchar(); scanf("%s%d%d",ch,&a,&b); if (ch[0]=='Q') { //cout<<"!!!!!!!!!!!!!!!!!"<<endl; int ans=SearchTree(a,b,1); printf ("%d ",ans); } else if (ch[0]=='U') { UpdataTree(a,b,1); } } } return 0; }