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


    题意

    q种操作,查询区间内最长连续上升子序列的长度,或者修改某个点的值

    题解

    线段树维护:区间内最长连续上升子序列的长度sub、区间内以左端点为起点的最长连续上升子序列的长度lsub、区间内以右端点为终点的最长连续上升子序列的长度rsub、区间左端点的值l和右端点的值r。

     1 #define IO std::ios::sync_with_stdio(0);
     2 #include <bits/stdc++.h>
     3 #define iter ::iterator
     4 using namespace  std;
     5 typedef long long ll;
     6 typedef pair<ll,ll>P;
     7 #define pb push_back
     8 #define se second
     9 #define fi first
    10 #define rs o*2+1
    11 #define ls o*2
    12 const ll inf=0x7fffffff;
    13 const int N=1e5+5;
    14 struct node{
    15     int sub;
    16     int lsub,rsub;
    17     int l,r;
    18 }a[N*4];
    19 void pu(int o,int len){
    20     a[o].l=a[ls].l;
    21     a[o].r=a[rs].r;
    22     a[o].sub=max(a[ls].sub,a[rs].sub);
    23     if(a[rs].l>a[ls].r){
    24         a[o].sub=max(a[o].sub,a[ls].rsub+a[rs].lsub);
    25     }
    26     a[o].lsub=a[ls].lsub;
    27     if(a[ls].lsub==len-len/2&&a[rs].l>a[ls].r){
    28         a[o].lsub+=a[rs].lsub;
    29     }
    30     a[o].rsub=a[rs].rsub;
    31     if(a[o].rsub==len/2&&a[rs].l>a[ls].r){
    32         a[o].rsub+=a[ls].rsub;
    33     }
    34 }
    35 void build(int o,int l,int r){
    36     if(l==r){
    37         int x;
    38         scanf("%d",&x);
    39         a[o].l=a[o].r=x;
    40         a[o].sub=a[o].lsub=a[o].rsub=1;
    41         return;
    42     }
    43     int m=(l+r)/2;
    44     build(ls,l,m);
    45     build(rs,m+1,r);
    46     pu(o,r-l+1);
    47 }
    48 void up(int o,int l,int r,int p,int v){
    49     if(l==r&&l==p){
    50         a[o].l=a[o].r=v;
    51         return;
    52     }
    53     int m=(l+r)/2;
    54     if(p<=m)up(ls,l,m,p,v);
    55     else up(rs,m+1,r,p,v);
    56     pu(o,r-l+1);
    57 }
    58 int query(int o,int l,int r,int ql,int qr){
    59     if(l>=ql&&r<=qr){
    60         return a[o].sub;
    61     }
    62     int m=(l+r)/2;
    63     int res=0;
    64     if(ql<=m)res=max(res,query(ls,l,m,ql,qr));
    65     if(qr>m)res=max(res,query(rs,m+1,r,ql,qr));
    66     if(ql<=m&&qr>m&&a[ls].r<a[rs].l){
    67         res=max(res,min(a[ls].rsub,m-ql+1)+min(a[rs].lsub,qr-m));
    68     }
    69     return res;
    70 }
    71 int T,n,q;
    72 int main(){
    73     scanf("%d",&T);
    74     while(T--){
    75         scanf("%d%d",&n,&q);
    76         build(1,1,n);
    77         char s[10];
    78         while(q--){
    79             int x,y;
    80             scanf("%s%d%d",s,&x,&y);
    81             x++;
    82             if(s[0]=='U')up(1,1,n,x,y);
    83             else{
    84                 y++;
    85                 printf("%d
    ",query(1,1,n,x,y));
    86             }
    87         }
    88     }
    89 }
  • 相关阅读:
    第一个java程序 Hello,World
    安装jdk,配置环境变量
    QQ传输大文件,服务器拒绝了你发送离线文件
    在WPF显示动态GIF图片
    Windows下预览svg
    WPF,ScrollViewer的属性VerticalScrollBarVisibility、HorizontalScrollBarVisibility值的区别
    未能添加对“*.dll”的引用
    端口被占用
    windows下安装tomcat
    编译安装Linux内核 centos版本
  • 原文地址:https://www.cnblogs.com/ccsu-kid/p/10626294.html
Copyright © 2020-2023  润新知