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


    http://acm.hdu.edu.cn/showproblem.php?pid=3308

    题意: 两个操作  : 1 修改 单点  a 处的值。

      2 求出 区间【a,b】内的最长上升子序列。

    做法:线段树区间合并。了解线段树的具体含义很容易。

     1 // by caonima
     2 // hehe
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <algorithm>
     6 #include <vector>
     7 #include <cmath>
     8 using namespace std;
     9 const int MAX= 1e5+10;
    10 int Lsum[MAX<<2],Rsum[MAX<<2],Msum[MAX<<2];
    11 int Lnum[MAX<<2],Rnum[MAX<<2];
    12 int a[MAX];
    13 char Q[10];
    14 
    15 void push_up(int o,int m) {
    16     Lsum[o]=Lsum[o<<1];
    17     Rsum[o]=Rsum[o<<1|1];
    18     Msum[o]=max(Msum[o<<1],Msum[o<<1|1]);
    19     Lnum[o]=Lnum[o<<1];
    20     Rnum[o]=Rnum[o<<1|1];
    21     if(Rnum[o<<1]<Lnum[o<<1|1]) {
    22         if(Lsum[o<<1]==(m-(m>>1))) Lsum[o]+=Lsum[o<<1|1];
    23         if(Rsum[o<<1|1]==(m>>1)) Rsum[o]+=Rsum[o<<1];
    24         Msum[o]=max(Msum[o],Rsum[o<<1]+Lsum[o<<1|1]);
    25     }
    26     return ;
    27 }
    28 
    29 void build(int L,int R,int o) {
    30     if(L==R) {
    31         Lsum[o]=Rsum[o]=Msum[o]=1;
    32         Lnum[o]=Rnum[o]=a[L];
    33         return ;
    34     }
    35     int mid=(L+R)>>1;
    36     build(L,mid,o<<1);
    37     build(mid+1,R,o<<1|1);
    38     push_up(o,R-L+1);
    39 }
    40 
    41 void Update(int L,int R,int o,int k,int val) {
    42     if(L==R) {
    43         Lnum[o]=Rnum[o]=val;
    44       //  Lsum[o]=Rsum[o]=Msum[o]=1;
    45         return ;
    46     }
    47     int mid=(L+R)>>1;
    48     if(k<=mid) Update(L,mid,o<<1,k,val);
    49     else Update(mid+1,R,o<<1|1,k,val);
    50     push_up(o,R-L+1);
    51 }
    52 
    53 int Query(int L,int R,int o,int ls,int rs) {
    54     if(ls<=L&&rs>=R) {
    55         return Msum[o];
    56     }
    57     int mid=(L+R)>>1;
    58     int ans=0;
    59     if(ls<=mid) ans=max(ans,Query(L,mid,o<<1,ls,rs));
    60     if(rs>mid) ans=max(ans,Query(mid+1,R,o<<1|1,ls,rs));
    61     if(Rnum[o<<1]<Lnum[o<<1|1])
    62     ans=max(ans,min(mid-ls+1,Rsum[o<<1])+min(rs-mid,Lsum[o<<1|1]));
    63     return ans;
    64 }
    65 
    66 int main() {
    67     int cas,n,m,ls,rs;
    68     scanf("%d",&cas);
    69     while(cas--) {
    70         scanf("%d %d",&n,&m);
    71         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    72         build(1,n,1);
    73         for(int i=1;i<=m;i++) {
    74             scanf("%s %d %d",Q,&ls,&rs);
    75             if(Q[0]=='Q') {
    76                 int res=Query(1,n,1,ls+1,rs+1);
    77                 printf("%d ",res);
    78             }
    79             else {
    80                 Update(1,n,1,ls+1,rs);
    81             }
    82         }
    83     }
    84     return 0;

    85 } 

  • 相关阅读:
    Git(一):基础调用
    Vue(一):使用Vue创建项目并发布
    mysql用户与权限
    跨域理解及常用解决方案
    Ajax简单用法
    冒泡排序算法
    委托使用方式
    How to: Add the Analyze Action to List Views 如何:将分析按钮添加到列表视图
    How to:Customize Action Controls 如何:自定义按钮控件
    How to: Customize the New Action's Items List 如何:自定义新按钮的项目列表
  • 原文地址:https://www.cnblogs.com/acvc/p/3885663.html
Copyright © 2020-2023  润新知