标签:str fine 长度 span ios ret turn iostream mat
题目大意:给予一个序列,两种操作
·查询 L-R 中的最长严格递增连续子序列的长度
·更改 LOC 的字符为X
经典的线段树区间合并,线段树种一共有三个数组
no[]当前 L到R中的最大值
ls[]从左数的最大长度
rs[]从右数的最大长度
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <algorithm> using namespace std; #define lowbit(x) (x&(-(x))) typedef long long ll; #define maxs 1000010 #define N 100005 #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 int num[N]; int no[N<<2],ls[N<<2],rs[N<<2]; void pushUp(int l,int r,int rt){ int mid = l+r>>1; ls[rt] = ls[rt<<1];rs[rt] = rs[rt<<1|1]; no[rt] = max(no[rt<<1],no[rt<<1|1]); if(num[mid] < num[mid+1]){ if(ls[rt] == mid-l+1)ls[rt]+=ls[rt<<1|1]; if(rs[rt] == r-mid)rs[rt]+=rs[rt<<1]; no[rt] = max(no[rt],ls[rt<<1|1]+rs[rt<<1]); } } void build(int l,int r,int rt){ if(l==r){ no[rt] = ls[rt] = rs[rt] = 1; return; } int mid = l+r>>1; build(lson);build(rson); pushUp(l,r,rt); } void upDate(int loc,int l,int r,int rt){ if(l==r)return; int mid = l+r>>1; if(loc<=mid)upDate(loc,lson); else upDate(loc,rson); pushUp(l,r,rt); } int query(int L,int R,int l,int r,int rt){ if(L <= l and r <= R)return no[rt]; int mid = l+r>>1; if(R <= mid)return query(L,R,lson); if(L > mid)return query(L,R,rson); int fi = query(L,R,lson); int se = query(L,R,rson); int ans = max(fi,se); if(num[mid] < num[mid+1]){ ans = max(ans,(min(R-mid,ls[rt<<1|1])+min(mid+1-L,rs[rt<<1]))); } return ans; } int main(){ int T,n,m; char c; int l,r; cin>>T; while (T--){ cin>>n>>m; for(int i = 1 ; i <= n ; ++i){ scanf("%d",num+i); } build(1,n,1); while (m--){ scanf(" %c",&c); scanf("%d%d",&l,&r); ++l; if(c==‘U‘){ num[l] = r; upDate(l,1,n,1); } else{ ++r; printf("%d\n",query(l,r,1,n,1)); } } } }
标签:str fine 长度 span ios ret turn iostream mat
原文地址:https://www.cnblogs.com/DevilInChina/p/9528803.html