• 51nod 1810 连续区间


    感觉跟中位数那题很像啊,不过简单一点还是不会

    大力分治,那么要求的就是左端点在左区间,右端点在右区间的满足是一个连续排列的数量

    对于一个连续的排列(设i是左端点j是右端点),有max-min+1=j-i+1

    那么分情况讨论

    枚举其中一个端点,若max,min都在这一边,那么可以计算另一端的端点

    否则有两个条件:mx[i]>mx[j]&&mn[i]>mn[j](mx在左mn在右,反过来也是类似的)考虑mx单调增,mn单调减,用两个指针扫描,对于j的延伸,mn一定满足条件,只需要判断mx是否满足。对于i的延伸,mx一定满足条件,只需要判断mn是否满足。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    
    #define v(i) v[i+1000010]
    using namespace std;
    typedef long long LL;
    
    int a[1100000],mx[1100000],mn[1100000];LL ans;
    int v[3100000];
    void solve(int l,int r)
    {
        if(l==r){ans++;return ;}
        int mid=(l+r)/2;
        solve(l,mid),solve(mid+1,r);
        
        mx[mid]=mn[mid]=a[mid];
        for(int i=mid-1;i>=l;i--)
            mx[i]=max(mx[i+1],a[i]), mn[i]=min(mn[i+1],a[i]);
        mx[mid+1]=mn[mid+1]=a[mid+1];
        for(int j=mid+2;j<=r;j++)
            mx[j]=max(mx[j-1],a[j]), mn[j]=min(mn[j-1],a[j]);
            
        for(int i=mid;i>=l;i--)
        {
            int L=mx[i]-mn[i]+1;
            int j=i+L-1;
            if(mid+1<=j&&j<=r&&mx[i]>mx[j]&&mn[i]<mn[j])ans++;
        }
        for(int j=mid+1;j<=r;j++)
        {
            int L=mx[j]-mn[j]+1;
            int i=j-L+1;
            if(l<=i&&i<=mid&&mx[j]>mx[i]&&mn[j]<mn[i])ans++;
        }
        
        int h=mid+1,t=mid+1;//mx在左,mn在右 
        for(int i=mid;i>=l;i--)
        {
            while(t<=r&&mx[i]>mx[t])v(mn[t]+t)++,t++;
            while(h<t&&mn[i]<mn[h])v(mn[h]+h)--,h++;
            ans+=v(mx[i]+i);
        }
        while(h<t)v(mn[h]+h)--,h++;
        
        h=mid,t=mid;
        for(int j=mid+1;j<=r;j++)
        {
            while(t>=l&&mx[j]>mx[t])v(mn[t]-t)++,t--;
            while(h>t&&mn[j]<mn[h])v(mn[h]-h)--,h--;
            ans+=v(mx[j]-j);
        }
        while(h>t)v(mn[h]-h)--,h--;
    }
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        ans=0;solve(1,n);
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    《数据结构和Java集合框架》第二章学习笔记
    《数据结构和Java集合框架》第一章学习笔记
    Arbotix关节控制器的实现(十)
    Arbotix关节控制器的实现(九)
    MoveIt编程实现机械臂自主避障运动(六)
    ROS机械臂开发_MoveIt!与机械臂控制(七)
    IOI2020国家集训队作业选做Part1
    模拟费用流问题略解
    PKUSC2021部分题目简要题解
    ARC 119部分题目简要题解
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9814355.html
Copyright © 2020-2023  润新知