Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)C. Compressed Bracket Sequence
括号序列肯定想到要转化成折线考虑,这个是经典操作就不解释了,想学的看 这里 有解释
(当然如果是比较短的括号序列求子合法序列可以用栈配合 dp 算,比如某道使我提前退役的题目)
这一题因为序列是压缩的,没法用一般的 dp 算
对于折线下降的某个位置,要算左边包含同高度的上升段数(且之间没有更低的折线段)
如图说明的一样:
注意到段数 n<=1000n<=1000 ,所以容易想到可以对每一下降段作为右端点,枚举前面的所有上升段作为左端点然后计算
要注意一种情况的处理:
具体看代码吧,实现起来挺恶心的,记得longlong longlong
#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\n",ans); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
2019-09-03 P4291 [HAOI2008]排名系统
2019-09-03 P4290 [HAOI2008]玩具取名
2019-09-03 P2218 [HAOI2007]覆盖问题
2018-09-03 P2044 [NOI2012]随机数生成器
2018-09-03 P1962 斐波那契数列