zoukankan      html  css  js  c++  java
  • BZOJ 4491 分块OR差分+线段树

    思路:

    (是不是只有我作大死写了个分块)

    up[i][j]表示从第i块开始到第j个位置 上升的最大值

    down[i][j]同理

    left_up[i]表示从第i块开始能够上升的最长长度

    left_down[i]同理

    right_up[i]表示从第i块结尾上升的最长长度

    right_down[i]同理

    然后就是各种恶心的分类讨论

    (见代码吧,,,,,,)

    嗯这道题还可以差分以后线段树维护>0的最长长度(左max 右max 区间max)

    //By SiriusRen
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=50050,inf=0x3f3f3f3f;
    int n,q,l,r,a[N],block[N],up[230][N],down[230][N],left_up[230],left_down[230],right_up[230],right_down[230];
    int main(){
        scanf("%d",&n);int Block=sqrt(n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)block[i]=(i-1)/Block+1;
        for(int i=1;i<=block[n];i++){
            int temp_up=1,temp_down=1,f_up=0,f_down=0;
            for(int j=lower_bound(block+1,block+1+n,i)-block;j<=n;j++){
                up[i][j]=max(up[i][j-1],temp_up),down[i][j]=max(temp_down,down[i][j-1]);
                if(!f_down)left_down[i]=temp_down;
                if(!f_up)left_up[i]=temp_up;
                if(a[j+1]>a[j])temp_up++,temp_down=1,f_down=1;
                else if(a[j+1]<a[j])temp_down++,temp_up=1,f_up=1;
                else temp_up++,temp_down++;
            }
        }
        for(int i=1;i<=block[n];i++){
            int temp=lower_bound(block+1,block+1+n,i)-block,j=upper_bound(block+1,block+1+n,i)-block-1,temp_up=1,temp_down=1;
            for(;block[j]==block[temp];j--){
                right_up[i]=max(right_up[i],temp_up),right_down[i]=max(right_down[i],temp_down);
                if(a[j-1]>a[j])temp_up++,temp_down=-inf;
                else if(a[j-1]<a[j])temp_down++,temp_up=-inf;
                else temp_up++,temp_down++;
            }
        }
        scanf("%d",&q);
        while(q--){
            scanf("%d%d",&l,&r);
            if(block[l]==block[r]){
                int ans=0;
                int temp_up=1,temp_down=1;
                for(int j=l;j<=r;j++){
                    ans=max(ans,max(temp_up,temp_down));
                    if(a[j+1]>a[j])temp_up++,temp_down=1;
                    else if(a[j+1]<a[j])temp_down++,temp_up=1;
                    else temp_up++,temp_down++;
                }
                printf("%d
    ",ans);
            }
            else{
                int L=block[l]+1,ans=max(up[L][r],down[L][r]),temp_up=1,temp_down=1;
                int beginL=lower_bound(block+1,block+1+n,L)-block;
                for(int j=l;j<beginL;j++){
                    ans=max(ans,max(temp_up,temp_down));
                    if(a[j+1]>a[j])temp_up++,temp_down=1;
                    else if(a[j+1]<a[j])temp_down++,temp_up=1;
                    else temp_up++,temp_down++;
                }
                if(a[beginL]>=a[beginL-1]){
                    int tmpx=min(right_down[L-1],beginL-l),tmpy=min(r-beginL+1,left_up[L]);
                    ans=max(ans,tmpx+tmpy);
                }
                if(a[beginL]<=a[beginL-1]){
                    int tmpx=min(right_up[L-1],beginL-l),tmpy=min(r-beginL+1,left_down[L]);
                    ans=max(ans,tmpx+tmpy);
                }
                printf("%d
    ",ans);
            }
        }
    }
  • 相关阅读:
    InfoPath 发布表单到SharePoint库报错
    在log4net中控制nhibernate输出
    微信扫一扫(wx.scanQRCode)功能新手可能遇到的问题
    3.Zookeeper的安装和配置(集群模式)
    1.配置HDFS HA (高可用)
    2.Zookeeper工作原理(详细)
    1.Zookeeper 定义与工作原理
    js 获取元素的几种方法
    弹出层居中
    XUACompatible
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6556423.html
Copyright © 2011-2022 走看看