LCIS HDU - 3308(線段樹)
阿新 • • 發佈:2018-11-05
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.
線段樹程式碼風格換成結構體了。來一道動態最大連續上升子序列。
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<string> #include<vector> #include<queue> #include<stack> #include<cmath> #include<set> #include<map> using namespace std; #define rep(i,a,n) for (int i=a;i<n;i++) #define per(i,a,n) for (int i=n-1;i>=a;i--) #define oo cout<<"!!!"<<endl; typedef long long ll; typedef unsigned long long ull; #define ms(s) memset(s, 0, sizeof(s)) const int inf = 0x3f3f3f3f; //head const int maxn = 1e6+11; int a[maxn]; struct node { int l,r,dat,dl,dr,len; }t[maxn]; void pushup(int i) { int m = (t[i].l + t[i].r)>>1; if(a[m] < a[m+1]) { t[i].dl = t[i<<1].dl == t[i<<1].len? (t[i<<1].dl + t[i<<1|1].dl) : t[i<<1].dl; t[i].dr = t[i<<1|1].dr == t[i<<1|1].len? (t[i<<1|1].dr + t[i<<1].dr) : t[i<<1|1].dr; t[i].dat = max(t[i<<1].dat,t[i<<1|1].dat); t[i].dat = max(t[i].dat,t[i<<1].dr + t[i<<1|1].dl); } else { t[i].dl = t[i<<1].dl; t[i].dr = t[i<<1|1].dr; t[i].dat = max(t[i<<1].dat,t[i<<1|1].dat); } } void build(int i,int l,int r) { t[i].l = l,t[i].r = r; t[i].len = r - l +1; if(l == r){t[i].dl = t[i].dr = t[i].dat = t[i].len = 1;return;} int m = (l+r)>>1; build(i<<1,l,m); build(i<<1|1,m+1,r); pushup(i); } void update(int p,int v,int i) { if(t[i].l == t[i].r) { return; } int mid = (t[i].l + t[i].r)>>1; if(p<=mid)update(p,v,i<<1); else update(p,v,i<<1|1); pushup(i); } int query(int ql,int qr,int i) { if(ql <= t[i].l && qr >= t[i].r) { return t[i].dat; } int mid = (t[i].l + t[i].r)>>1; if(qr<=mid)return query(ql,qr,i<<1); if(ql>mid)return query(ql,qr,i<<1|1); int len = query(ql,qr,i<<1); int ren = query(ql,qr,i<<1|1); int ans = max(len,ren); if(a[mid] < a[mid+1]) { int tmp = min(t[i<<1].dr,mid-ql+1) + min(t[i<<1|1].dl,qr-mid); ans = max(ans,tmp); } return ans; } int main() { int T;cin>>T; while(T--) { int n,m; cin>>n>>m; rep(i,1,n+1)scanf("%d",a+i); build(1,1,n); while(m--) { char op[11]; int x,y; scanf("%s%d%d",op,&x,&y); if(op[0] == 'U') { a[x+1] = y; update(x+1,y,1); } else { printf("%d\n",query(x+1,y+1,1)); } } } return 0; }