zoukankan      html  css  js  c++  java
  • 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 } 

  • 相关阅读:
    Tarjan在图论中的应用(三)——用Tarjan来求解2-SAT
    【CodeForces】CodeForcesRound594 Div1 解题报告
    JS面向对象组件(三)--面向对象中的常用属性和方法
    JS面向对象组件(二)--Javascript原型链
    JS面向对象组件(一) ---包装对象与原型链
    JS面向对象组件(六) -- 拖拽功能以及组件的延展
    面试题目
    webstorm安装破解版
    面试题整理
    Javascript模块化编程(三):require.js的用法 (转)
  • 原文地址:https://www.cnblogs.com/acvc/p/3885663.html
Copyright © 2011-2022 走看看