zoukankan      html  css  js  c++  java
  • LCIS

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

    题意:给你 100000个数列,然后更新某个点,然后查询区间内最长连续上升数列的长度,用线段树来维护区间的最大连续值,左连续最大值,右连续最大值,区间的左端点,区间的右端点。对于更新,父节点的最大值,首先求左儿子的最大值,右儿子的最大值,比较,选出大者,如果左儿子的又端点小于右儿子的左端点,则要考虑左儿子的右连续+右儿子的左连续是否大于刚才的那个值,选出大的更新。对于父节点的左连续,如果左儿子的左连续等于区间长度则父节点的左连续等于左儿子的左连续+右儿子的左连续,同理更新父节点的右连续。左端点等于左儿子的左端点,同理右端点。
     对于查询:返回类型是节点类型。如果是在左儿子那里,则进入左儿子,如果在右边,则进入右儿子。如果在中间,则分别求出左边的和右边的,然后处理把这两个节点当做左儿子和右儿子进行, 对new出来的父节点进行新 。然后返回父节点。

      1 #include<cstring>
      2 #include<algorithm>
      3 #include<cstdio>
      4 #include<iostream>
      5 using namespace std;
      6 struct Node{
      7     int left;
      8     int right;
      9     int lsum,rsum,sum;
     10     int lmax,rmax;
     11 }node[100003<<2];
     12 int u,v,n,m;
     13 void pushup(int idx){
     14     if(node[idx<<1].rmax<node[idx<<1|1].lmax){
     15      node[idx].sum=node[idx<<1].rsum+node[idx<<1|1].lsum;
     16      node[idx].sum=max(node[idx<<1].sum,max(node[idx].sum,node[idx<<1|1].sum));
     17     }
     18     else
     19      node[idx].sum=max(node[idx<<1].sum,node[idx<<1|1].sum);
     20     if(node[idx<<1].lsum==node[idx<<1].right-node[idx<<1].left+1&&node[idx<<1].rmax<node[idx<<1|1].lmax)
     21        node[idx].lsum=node[idx<<1].lsum+node[idx<<1|1].lsum;
     22     else
     23       node[idx].lsum=node[idx<<1].lsum;
     24      if(node[idx<<1|1].rsum==node[idx<<1|1].right-node[idx<<1|1].left+1&&node[idx<<1].rmax<node[idx<<1|1].lmax)
     25        node[idx].rsum=node[idx<<1].rsum+node[idx<<1|1].rsum;
     26      else 
     27        node[idx].rsum=node[idx<<1|1].rsum;
     28        node[idx].lmax=node[idx<<1].lmax;
     29        node[idx].rmax=node[idx<<1|1].rmax;
     30 }
     31 void build(int l,int r,int idx){
     32     node[idx].left=l;
     33     node[idx].right=r;
     34     if(l==r){
     35         scanf("%d",&node[idx].lmax);
     36     node[idx].rmax=node[idx].lmax;
     37     node[idx].lsum=node[idx].rsum=node[idx].sum=1;
     38     return;
     39     }
     40     int mid=(l+r)/2;
     41     build(l,mid,idx<<1);
     42     build(mid+1,r,idx<<1|1);
     43     pushup(idx);
     44 }
     45 void update(int pos,int val,int idx){
     46     if(node[idx].left==node[idx].right){
     47         node[idx].lmax=node[idx].rmax=val;
     48         return;
     49     }
     50     int mid=(node[idx].left+node[idx].right)/2;
     51     if(mid>=pos)update(pos,val,idx<<1);
     52     else
     53     update(pos,val,idx<<1|1);
     54     pushup(idx);
     55 }
     56 Node  query(int s,int t,int idx){
     57     if(node[idx].left==s&&node[idx].right==t){
     58         return node[idx];
     59     }
     60     int mid=(node[idx].right+node[idx].left)/2;
     61     Node a,b,c;
     62     if(mid>=t)return query(s,t,idx<<1);
     63     else if(mid<s)return query(s,t,idx<<1|1);
     64     else{
     65           a=query(s,mid,idx<<1);
     66           b=query(mid+1,t,idx<<1|1);
     67     if(a.rmax<b.lmax){
     68      c.sum=a.rsum+b.lsum;
     69      c.sum=max(a.sum,max(c.sum,b.sum));
     70     }
     71     else
     72      c.sum=max(a.sum,b.sum);
     73     if(a.lsum==a.right-a.left+1&&a.rmax<b.lmax)
     74        c.lsum=a.lsum+b.lsum;
     75     else
     76       c.lsum=a.lsum;
     77      if(b.rsum==b.right-b.left+1&&a.rmax<b.lmax)
     78        c.rsum=a.rsum+b.rsum;
     79      else 
     80        c.rsum=b.rsum;
     81        c.lmax=a.lmax;
     82        c.rmax=b.rmax;
     83        return c;
     84        }
     85 }
     86 int main(){
     87     int cas;char c;
     88     scanf("%d",&cas);
     89     while(cas--){
     90         scanf("%d%d",&n,&m);
     91         build(1,n,1);
     92         for(int i=1;i<=m;i++){
     93             cin>>c>>u>>v;
     94             if(c=='Q')
     95              printf("%d
    ",query(u+1,v+1,1).sum);
     96              else
     97                update(u+1,v,1);
     98         }
     99     }
    100 }
    101  
    View Code
  • 相关阅读:
    Oracle配置监听
    Oracle创建表空间和分配用户权限
    Dijkstra
    【刷题】【dp】【记忆化搜索】单词游戏
    【刷题】【记忆化搜索】【dp】Longtail Hedgehog
    【刷题】【dp】 Make The Fence Great Again
    【技巧】【卡常】
    【二分】【基础】(跳石头)(合并果子)(蚯蚓)
    【笔记】两种交换元素的方案对比
    【刷题】【单调栈】请客
  • 原文地址:https://www.cnblogs.com/chujian123/p/3432284.html
Copyright © 2011-2022 走看看