CF1550C 题解
前言
比赛时,这题写了一个
以为是数据水,实际上可以证明时间复杂度是
思路
关键是一个结论:当
为什么呢?画个图就很容易理解了。
同理,单调不增也是这样的。
所以,我们利用这一点 check
函数。
const int N = 2e5 + 5;
int a[N];
bool chk(int l, int r) // [l,r] 区间是否是坏的
{
for (int i = l; i < r; i++)
for (int j = l; j < i; j++) //j<i<r
{
if (a[j] <= a[i] && a[i] <= a[r]) return true;
if (a[j] >= a[i] && a[i] >= a[r]) return true; //符号反过来
}
return false;
}
接着打个尺取,即可在
void solve()
{
int n;
long long cnt = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int l = 1, r = 1; r <= n; r++) //顺序枚举右端点,左端点尺取
{
for (; l <= r && chk(l, r); l++);
cnt += (r - l + 1);
}
printf("%lld\n", cnt);
}
那为什么可以跑过去呢?原因在于,
画一个图,可以发现,不会有长度大于等于
所以这个方法去掉常数,就是
完整代码
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 2e5 + 5;
int a[N];
bool chk(int l, int r)
{
for (int i = l; i < r; i++)
for (int j = l; j < i; j++)
{
if (a[j] <= a[i] && a[i] <= a[r]) return true;
if (a[j] >= a[i] && a[i] >= a[r]) return true; //符号反过来
}
return false;
}
void solve()
{
int n;
long long cnt = 0;
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int l = 1, r = 1; r <= n; r++)
{
for (; l <= r && chk(l, r); l++);
cnt += (r - l + 1);
}
printf("%lld\n", cnt);
}
int main()
{
int T;
scanf("%d", &T);
while (T--) solve();
return 0;
}
希望能帮助到大家!
首发:2022-08-09 07:39:00
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】