当前位置: 代码迷 >> 综合 >> HDU 3308 LCIS (线段树区间合并)
  详细解决方案

HDU 3308 LCIS (线段树区间合并)

热度:97   发布时间:2023-11-15 16:55:18.0

LCIS

Time Limit : 6000/2000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 1   Accepted Submission(s) : 1

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

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<=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

Author

shǎ崽

Source

HDOJ Monthly Contest – 2010.02.06
#include <queue>
#include <iostream>
#include<cstring>
#include<stdio.h>
#define maxn 100050
using namespace std;
int n,m,x,y;
char c;
/*
区间合并;
该程序没有剪枝就过了,估计是数据水吧。。。
如果有两个区间,如何设定标准值并进行操作把它合并成一个区间呢。
首先肯定需要两个子区间的最长长度,
然后对大区间的中间部分进行判定,
依次递推下标。。。得到另外一个判断值,再代入比较
*/
struct node
{int l,r;int v,maxl;//最长长度int lc,rc;node(){lc=rc=0;l=r=v=maxl=0;}
};
node seq[maxn<<2];
int num[maxn];void pushup(int rt)
{int rr=seq[rt<<1].r,ll=seq[rt<<1|1].l;int nlc,nrc,tmp;seq[rt].maxl=max(seq[rt<<1].maxl,seq[rt<<1|1].maxl);if(seq[rt].maxl==seq[rt<<1].maxl){seq[rt].lc=seq[rt<<1].lc,seq[rt].rc=seq[rt<<1].rc;}else if(seq[rt].maxl==seq[rt<<1|1].maxl){seq[rt].lc=seq[rt<<1|1].lc,seq[rt].rc=seq[rt<<1|1].rc;}if(num[ll]>num[rr]){nlc=rr,nrc=ll;while(nrc+1<=seq[rt<<1|1].r&&num[nrc]<num[nrc+1])nrc++;while(nlc-1>=seq[rt<<1].l&&num[nlc]>num[nlc-1])nlc--;seq[rt].maxl=max(seq[rt].maxl,nrc-nlc+1);if(seq[rt].maxl==nrc-nlc+1)seq[rt].lc=nlc,seq[rt].rc=nrc;}
}void build(int l,int r,int rt)
{seq[rt].l=l;seq[rt].r=r;if(l==r){seq[rt].lc=seq[rt].rc=l;seq[rt].v=num[l];seq[rt].maxl=1;return ;}int mid=(l+r)>>1;build(l,mid,rt<<1);build(mid+1,r,rt<<1|1);pushup(rt);
}void update(int p,int rt,int val)
{if(seq[rt].l==seq[rt].r){seq[rt].v=num[seq[rt].l]=val ;return ;}int mid=(seq[rt].l+seq[rt].r)>>1;if(mid>=p)  update(p,rt<<1,val);else update(p,rt<<1|1,val);pushup(rt);
}int query(int l,int r,int rt)
{if(seq[rt].l>=l&&seq[rt].r<=r)return seq[rt].maxl;int mid=(seq[rt].l+seq[rt].r)>>1;int max1=0,max2=0,maxx=-1;int nl=0,nr=0;if(mid>=l)max1=query(l,r,rt<<1);if(r>mid)max2=query(l,r,rt<<1|1);maxx=max(max1,max2);if(max1&&max2){nl=mid,nr=mid+1;if(num[nl]<num[nr]){while(nr+1<=r&&num[nr]<num[nr+1])nr++;while(nl-1>=l&&num[nl]>num[nl-1])nl--;}elsenl=nr=0;}return max(maxx,nr-nl+1);
}int main()
{ios::sync_with_stdio(false);int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)  scanf("%d",&num[i]);getchar();build(1,n,1);while(m--){//scanf("%c",&c);cin>>c;if(c=='U'){cin>>x>>y;//scanf("%d%d",&x,&y);x++;update(x,1,y);}else{cin>>x>>y;//scanf("%d%d",&x,&y);x++,y++;cout<<query(x,y,1)<<endl;}}}return 0;
}