• hdu3308LCIS(线段树区间合并)


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

    注意两个地方 向上更新 和查找的时候

    向上更新

    1. 左儿子最右边的值 < 右儿子最左边的值

        lMax = (左儿子的lMax == 左儿子的len) ? 左儿子的len + 右儿子的lMax : 左儿子的lMax;
        rMax = (右儿子的rMax == 右儿子的len) ? 右儿子的len + 左儿子的rMax : 右儿子的rMax;
        Max  = MAX(左儿子的rMax + 右儿子的lMax, 左儿子的Max, 右儿子的Max, lMax, rMax);

    2. 左儿子最右边的值 >= 右儿子最左边的值

        lMax = 左儿子的lMax;
        rMax = 右儿子的rMax;
        Max  = MAX(左儿子的Max, 右儿子的Max);

    查找的时候 也分开来比较

    View Code
      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<stdlib.h>
      5 #include<algorithm>
      6 using namespace std;
      7 #define N 100010
      8 int s[N<<2],mm[N<<2],lm[N<<2],rm[N<<2],len[N<<2];
      9 void update(int l,int r,int w)
     10 {
     11     int m = (l+r)>>1;
     12     if(s[m]<s[m+1])
     13     {
     14         lm[w] = (lm[w<<1]==len[w<<1])?(lm[w<<1]+lm[w<<1|1]):lm[w<<1];
     15         rm[w] = (rm[w<<1|1]==len[w<<1|1])?(rm[w<<1|1]+rm[w<<1]):rm[w<<1|1];
     16         mm[w] = max((rm[w<<1]+lm[w<<1|1]),mm[w<<1]);
     17         mm[w] = max(lm[w],mm[w]);
     18         mm[w] = max(rm[w],mm[w]);
     19         mm[w] = max(mm[w<<1|1],mm[w]);
     20     }
     21     else
     22     {
     23         lm[w] = lm[w<<1];
     24         rm[w] = rm[w<<1|1];
     25         mm[w] = max(mm[w<<1],mm[w<<1|1]);
     26     }
     27 }
     28 int search(int a,int b,int l,int r,int w)
     29 {
     30     if(a<=l&&b>=r)
     31     {
     32         return mm[w];
     33     }
     34     int m = (l+r)>>1;
     35     if(b<=m)
     36     return search(a,b,l,m,w<<1);
     37     if(a>m)
     38     return search(a,b,m+1,r,w<<1|1);
     39     int len,ren,ans ;
     40     len = search(a,b,l,m,w<<1);
     41     ren = search(a,b,m+1,r,w<<1|1);
     42     ans = max(len,ren);
     43     if(s[m]<s[m+1])
     44     {
     45         int re;
     46         re=min(rm[w<<1],m-a+1)+min(lm[w<<1|1],b-m);
     47         ans=max(re,ans);
     48     }
     49     return ans;
     50 }
     51 void build(int l,int r,int w)
     52 {
     53     len[w] = (r-l+1);
     54     if(l==r)
     55     {
     56         mm[w] = 1;
     57         lm[w] = 1;
     58         rm[w] = 1;
     59         return ;
     60     }
     61     int m = (l+r)>>1;
     62     build(l,m,w<<1);
     63     build(m+1,r,w<<1|1);
     64     update(l,r,w);
     65 }
     66 void change(int p,int d,int l,int r,int w)
     67 {
     68     if(l==r&&l==p)
     69     {
     70         return ;
     71     }
     72     int m = (l+r)>>1;
     73     if(p<=m)
     74     change(p,d,l,m,w<<1);
     75     else
     76     change(p,d,m+1,r,w<<1|1);
     77     update(l,r,w);
     78 }
     79 int main()
     80 {
     81     int i,j,k,n,m,t,a,b;
     82     char c;
     83     cin>>t;
     84     while(t--)
     85     {
     86         cin>>n>>m;
     87         for(i = 1; i <= n ; i++)
     88         scanf("%d",&s[i]);
     89         build(1,n,1);
     90         while(m--)
     91         {
     92             cin>>c>>a>>b;
     93             if(c=='U')
     94             {
     95                 s[a+1] = b;
     96                 change(a+1,b,1,n,1);
     97             }
     98             else
     99             {
    100                 cout<<search(a+1,b+1,1,n,1)<<endl;
    101             }
    102         }
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    hdu 4651 Partition (利用五边形定理求解切割数)
    单点登录SSO的实现原理
    高速排序算法
    2014 百度之星第三题
    TR069协议向导——一个帮助你了解TR069协议的简明教程(一)
    教你用笔记本破解无线路由器password
    人脸识别算法初次了解
    JSP验证码
    GROUP BY,WHERE,HAVING之间的差别和使用方法
    typedef函数指针使用方法
  • 原文地址:https://www.cnblogs.com/shangyu/p/2976101.html
Copyright © 2020-2023  润新知