HDOJ 3308 LCIS (线段树之区间合并)
2017-04-03 23:34
316 查看
LCIS
[b]Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7349 Accepted Submission(s): 3110
[/b]
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].
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).
Output
For each Q, output the answer.Sample Input
110 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
11
4
2
3
1
2
5
#include <bits/stdc++.h> using namespace std; #define mst(a,b) memset((a),(b),sizeof(a)) #define f(i,a,b) for(int i=(a);i<(b);++i) const int maxn =10005; const int mod = 10005; const int INF = 1e9; #define ll long long #define m ((l+r)>>1) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define rush() int T;scanf("%d",&T);while(T--) int msum[maxn<<2]; //区间内最长连续递增子序列长度. int lsum[maxn<<2]; //从第一个数开始算起 到a[m]的最大连续递增序列长度 int rsum[maxn<<2]; //从a[m+1]开始算起 到最后一个数的最大连续递增序列长度 int num[maxn]; void pushup(int l,int r,int rt) { lsum[rt]=lsum[rt*2]; rsum[rt]=rsum[rt*2+1]; msum[rt]=max(msum[rt*2],msum[rt*2+1]); int len=r-l+1; if(num[m]<num[m+1]) { if(lsum[rt]==len-(len/2)) lsum[rt]+=lsum[rt*2+1]; if(rsum[rt]==len/2) rsum[rt]+=rsum[rt*2]; msum[rt]=max(msum[rt],lsum[rt*2+1]+rsum[rt*2]); } } void build(int l,int r,int rt) { if(l==r) { msum[rt]=lsum[rt]=rsum[rt]=1; return ; } build(lson); build(rson); pushup(l,r,rt) ; } void update(int p,int l,int r,int rt) { if(l==r) return; if(p<=m) update(p,lson); else update(p,rson); pushup(l,r,rt); } int query(int x,int y,int l,int r,int rt) { if(x<=l&&r<=y) { return msum[rt]; } if(y<=m) return query(x,y,lson); if(x>m) return query(x,y,rson); int a,b; a=query(x,y,lson); b=query(x,y,rson); int ans; ans=max(a,b); if(num[m]<num[m+1]) //区间合并 { int c; c=min(rsum[rt*2],m-x+1)+min(lsum[rt*2+1],y-m);//防炸 ans=max(c,ans); } return ans; } int main() { int t; scanf("%d",&t); while(t--) { int n,M; mst(lsum,0),mst(rsum,0),mst(msum,0),mst(num,0); scanf("%d%d",&n,&M); f(i,1,n) { scanf("%d",&num[i]); } build(1,n,1); while(M--) { char ch[2]; scanf("%s",ch); int a,b; scanf("%d%d",&a,&b); if(ch[0]=='U') { a++; num[a]=b; update(a,1,n,1); } else { a++,b++; printf("%d\n",query(a,b,1,n,1)); } } } return 0; }
相关文章推荐
- [HDOJ3308]LCIS(线段树,区间合并)
- [HDOJ3308]LCIS(线段树,区间合并,新的代码)
- HDOJ 3308 LCIS(线段树区间合并与查询)
- hdoj 3308 LCIS 【线段树单点更新 + 区间合并】【求解最长递增序列 的长度】
- HDOJ 题目3308 LCIS(线段树,区间查询,区间合并)
- HDOJ 题目3308 LCIS(线段树,区间查询,区间合并)
- 线段树(区间合并) HDOJ 3308 LCIS
- HDU 3308 LCIS(线段树单点更新区间合并)
- HDU 3308 LCIS(线段树区间合并)
- hdu--3308 LCIS(线段树+区间合并)
- HDU - 3308 - LCIS (线段树 - 区间合并)
- HDU 3308 LCIS(线段树区间合并)
- hdu 3308 LCIS 最大连续递增字串长 线段树区间合并
- [HDU 3308]LCIS[线段树][区间合并]
- HDU 3308 LCIS (线段树区间合并)
- HDU 3308 LCIS 最长上升字串(线段树区间合并)
- hdu 3308 LCIS (线段树+单点更新+区间合并)
- HDU 3308 LCIS (线段树合并区间)
- HDU 3308——LCIS(线段树,区间合并,最长连续递增子序列)
- HDU 3308 - LCIS(线段树+区间合并)