zoukankan      html  css  js  c++  java
  • Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)C. Compressed Bracket Sequence

    传送门

    括号序列肯定想到要转化成折线考虑,这个是经典操作就不解释了,想学的看 这里 有解释

    (当然如果是比较短的括号序列求子合法序列可以用栈配合 dp 算,比如某道使我提前退役的题目

    这一题因为序列是压缩的,没法用一般的 dp 算

    对于折线下降的某个位置,要算左边包含同高度的上升段数(且之间没有更低的折线段)

    如图说明的一样:

    注意到段数 $n<=1000$ ,所以容易想到可以对每一下降段作为右端点,枚举前面的所有上升段作为左端点然后计算

    要注意一种情况的处理:

     具体看代码吧,实现起来挺恶心的,记得$long$ $long$

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N=2e5+7;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    int n;
    ll r[N];//维护每一段的右端点
    ll ans;
    ll cal(ll x,ll y,ll p,ll q)//求区间 [x,y] 和区间 [p,q] 的交集大小
    {
        if(p>q||x>y) return 0;
        if(x>q||y<p||p>y||q<x) return 0;
        if(x<=p&&y<=q) return y-p+1;
        if(p<=x&&q<=y) return q-x+1;
        if(x>=p&&y<=q) return y-x+1;
        if(x<=p&&y>=q) return q-p+1;
    }
    int main()
    {
        n=read(); int c;
        for(int i=1;i<=n;i++)
        {
            c=read();
            if(i&1) r[i]=r[i-1]+c;
            else r[i]=r[i-1]-c;//判断段是上升还是下降
            if(i&1) continue;//只以下降段位右端点
            ll x=r[i],y=r[i-1];//确定下降段的区间
            ll p=r[i-2],q=r[i-1];//对左边第一个上升段特判,因为左边第一段的右端点和当前下降段左端点重合
            ans+=cal(x,y,p,q)-1;//注意-1
            for(int j=i-3;j>0;j-=2)//找更前面的上升段
            {
                //p,q维护当前上升段的合法区间
                if(r[j-1]>p) continue;//这个特判很关键,自己画图理解qwq
                q=min(q,p);
                p=min(p,r[j-1]);//这个p,q的更新可以参考我的图
                ans+=cal(x,y,p,q);//累加答案
            }
        }
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    Linux下JDK安装位置
    Oracle中的User与Schema
    MFC中不同窗口间的切换
    MFC 动态的画线 画当前的线是清除上一次画的线
    VC ADO连接ACCESS步骤及错误处理
    虚继承和虚函数继承
    虚拟机无法连接连接U盘
    未能找到类型或命名空间
    VS2008 重构 封装字段 出错 无法使用
    vs2010 Visual Studio 遇到了异常。这可能是由某个扩展导致的
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/15224908.html
Copyright © 2011-2022 走看看