题目描述

  有两个指针\(l,r\),初始时\(l=r=k\)

  给你\(a_1,\ldots,a_n\),你要移动\(l,r\),\(l\)只能每次向左移一个数,\(r\)只能向右移一个数,要求任意时刻\((l,r]\)这个区间内的数的和\(\leq 0\)

  求\(l,r\)能否都移动到端点。

  \(n\leq 100000\)

题解

  求前缀和\(s\),约束转化为任意时刻\(s_l\geq s_r\)。

  每一个时刻的决策是:

  如果\(l\)能在合法的情况下移动到\(l'\),满足\(s_{l'}>s_l\),且是所有合法的位置中最大的,就把\(l\)移到\(l'\)。\(r\)同理。

  如果左边的最小值\(<\)右边的当前位置,就无解。

  否则只能贪心移动了。这种情况左边右边剩下的\(s\)都在\([s_l,s_r]\)内。

  如果左边的最大值小于右边的最大值,就把\(r\)向右移一位,否则就把\(l\)向左移一位。

  时间复杂度:\(O(n)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll s[100010];
ll a[100010];
int fl[100010];
int fr[100010];
ll premax[100010];
ll sufmax[100010];
ll premin[100010];
ll sufmin[100010];
const ll inf=0x3fffffffffffffffll;
int sl1[100010];
ll sl2[100010];
int sr1[100010];
ll sr2[100010];
int st[100010];
int top;
int solve()
{
int n,k;
scanf("%d%d",&n,&k);
s[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
s[i]=s[i-1]+a[i];
}
premax[0]=-inf;
premin[0]=inf;
for(int i=1;i<=n;i++)
{
premax[i]=max(s[i],premax[i-1]);
premin[i]=min(s[i],premin[i-1]);
}
sufmax[n+1]=-inf;
sufmin[n+1]=inf;
for(int i=n;i>=1;i--)
{
sufmax[i]=max(s[i],sufmax[i+1]);
sufmin[i]=min(s[i],sufmin[i+1]);
}
top=0;
for(int i=1;i<=n;i++)
{
sl2[i]=s[i];
while(top&&s[st[top]]<s[i])
{
sl2[i]=min(sl2[i],sl2[st[top]]);
top--;
}
if(top)
sl1[i]=st[top];
else
sl1[i]=i;
st[++top]=i;
}
top=0;
for(int i=n;i>=1;i--)
{
sr2[i]=s[i];
while(top&&s[st[top]]>s[i])
{
sr2[i]=max(sr2[i],sr2[st[top]]);
top--;
}
if(top)
sr1[i]=st[top];
else
sr1[i]=i;
st[++top]=i;
}
int l=k,r=k;
while(1)
{
if(l!=1&&sl1[l]!=l&&sl2[l]>=s[r])
{
l=sl1[l];
continue;
}
if(r!=n&&sr1[r]!=r&&sr2[r]<=s[l])
{
r=sr1[r];
continue;
}
if(l==1)
{
if(sufmax[r]>s[l])
return 0;
return 1;
}
if(r==n)
{
if(premin[l]<s[r])
return 0;
return 1;
}
if(premax[l-1]<sufmax[r+1])
if(s[r+1]<=s[l])
r++;
else
return 0;
else
if(s[l-1]>=s[r])
l--;
else
return 0;
}
return 1;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
#endif
int t;
scanf("%d",&t);
while(t--)
if(solve())
printf("Yes\n");
else
printf("No\n");
return 0;
}

【XSY2787】Mythological VII 贪心的更多相关文章

  1. hdu5338 ZZX and Permutations(贪心、线段树)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud ZZX and Permutations Time Limit: 6000/300 ...

  2. codeforces 335A Banana(贪心)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud    Banana Piegirl is buying stickers for ...

  3. HUD 1288 Hat's Tea(反向的贪心,非常好的一道题)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1288 Hat's Tea Time Limit: 2000/1000 MS (Java/Others)  ...

  4. 【BZOJ5249】IIIDX(贪心,线段树)

    题意: 思路:赛季结束之前余总推荐的一道好题,不愧是余总 From https://www.cnblogs.com/suika/p/8748115.html 简略的说就是在预留足够多的位置的前提下贪心 ...

  5. 【CF1249F】Maximum Weight Subset(贪心)

    题意:给定一棵n个点带点权的树,要求从中选出一个点集,使得这些点两两之间距离都大于K,求最大点权和 n,K<=2e2,1<=a[i]<=1e5 思路:树形DP显然可做,极限是n方,然 ...

  6. 【CF1249D】Too Many Segments(贪心,set,vector)

    题意:给定n条线段和覆盖上限k,每条线段都覆盖了区间内的整点 问最少删掉几条线段能使所有的整点都被覆盖不超过k次 k<=n<=2e5,l[i],r[i]<=2e5 思路:比赛时候不会 ...

  7. 【CF1210B】Marcin and Training Camp(贪心)

    题意:有n个人,60种技能点,如果第i个人会第j种技能a[i]的二进制表示的第j位就是1,第i个人的价值是b[i] 如果有若干种技能i会j不会,i就会鄙视j 求一种至少两个人的选人方案使得价值和最大, ...

  8. BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1383  Solved: 582[Submit][St ...

  9. HDOJ 1051. Wooden Sticks 贪心 结构体排序

    Wooden Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

随机推荐

  1. 获取Oracle过程中的OUT SYS_REFCURSOR值

    一个项目中的实例:获取Oracle过程中的返回SYS_REFCURSOR.注意:如果SYS_REFCURSOR为一个表或视图.可以通过表名%ROWTYPE获取每行数据,而不必另外定义type. 原过程 ...

  2. vue 饿了么项目笔记

    vue 饿了么项目 1.图标字体引用 链接 2.scss 二三倍图切换 1像素边框 链接 3.better-scroll 4.布局 商品主页面 <div id="app"&g ...

  3. 【redis】windows 怎样关闭redis

    安装redis之后在命令行窗口中输入 redis-server redis.windows.conf 启动redis关闭命令行窗口就是关闭 redis.---redis作为windows服务启动方式r ...

  4. kattis Programming Tutors 给游客与导游匹配(二分+二分图)

    题目来源:https://vjudge.net/problem/Kattis-programmingtutors 题意: 有n个游客,n个导游,给出他们的坐标,问你怎么匹配可以使他们最大距离最小 题解 ...

  5. 福州大学软件工程1816 | W班 团队Alpha阶段成绩汇总排名(第9、10次作业)

    写在前面 汇总成绩排名链接 1.作业链接 第九次作业--项目Alpha冲刺(团队) 第十次作业--事后诸葛亮(团队) 2.评分准则 本次作业包括现场Alpha答辩评分(映射总分为100分)+博客分(总 ...

  6. Codeforces Round #546 (Div. 2)

    http://codeforces.com/contest/1136 A #include <bits/stdc++.h> using namespace std; ; int N, K; ...

  7. TCP 握手和挥手图解(有限状态机)

    1.引言 TCP 这段看过好几遍,老是记不住,没办法找工作涉及到网络编程这块,各种问 TCP .今天好好整理一下握手和挥手过程.献给跟我一样忙碌,找工作的童鞋,欢迎大神批评指正. 2.TCP 的连接建 ...

  8. withRouter使用

    import React from 'react'; import {Switch,NavLink,Route,Redirect,withRouter} from 'react-router-dom' ...

  9. Bootstrap知识记录:表单和图片

    一.表单Bootstrap 提供了一些丰富的表单样式供开发者使用.1.基本格式//实现基本的表单样式<form><div class="form-group"&g ...

  10. Windows BAT 命令下del 与 rd 命令

    https://blog.csdn.net/jigetage/article/details/81180757 RD 与 DEL 命令 windows bat 目录和文件的删除处理. 命令:RD,删除 ...