【XSY2787】Mythological VII 贪心
题目描述
有两个指针\(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 贪心的更多相关文章
- hdu5338 ZZX and Permutations(贪心、线段树)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud ZZX and Permutations Time Limit: 6000/300 ...
- codeforces 335A Banana(贪心)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Banana Piegirl is buying stickers for ...
- HUD 1288 Hat's Tea(反向的贪心,非常好的一道题)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1288 Hat's Tea Time Limit: 2000/1000 MS (Java/Others) ...
- 【BZOJ5249】IIIDX(贪心,线段树)
题意: 思路:赛季结束之前余总推荐的一道好题,不愧是余总 From https://www.cnblogs.com/suika/p/8748115.html 简略的说就是在预留足够多的位置的前提下贪心 ...
- 【CF1249F】Maximum Weight Subset(贪心)
题意:给定一棵n个点带点权的树,要求从中选出一个点集,使得这些点两两之间距离都大于K,求最大点权和 n,K<=2e2,1<=a[i]<=1e5 思路:树形DP显然可做,极限是n方,然 ...
- 【CF1249D】Too Many Segments(贪心,set,vector)
题意:给定n条线段和覆盖上限k,每条线段都覆盖了区间内的整点 问最少删掉几条线段能使所有的整点都被覆盖不超过k次 k<=n<=2e5,l[i],r[i]<=2e5 思路:比赛时候不会 ...
- 【CF1210B】Marcin and Training Camp(贪心)
题意:有n个人,60种技能点,如果第i个人会第j种技能a[i]的二进制表示的第j位就是1,第i个人的价值是b[i] 如果有若干种技能i会j不会,i就会鄙视j 求一种至少两个人的选人方案使得价值和最大, ...
- BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]
1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1383 Solved: 582[Submit][St ...
- HDOJ 1051. Wooden Sticks 贪心 结构体排序
Wooden Sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
随机推荐
- c++学习之字符串拼接
在这里,强调这样一个问题: 可以看出,c++中,定义了string类,string 类方便我们进行字符串的一些操作,而不是像C语言中采用字符数组的方式或者指针的方式,通过上面的一些描述,可以发现: s ...
- Python_函数的有用信息、带参数的装饰器、多个装饰器装饰一个函数
函数的有用信息 代码1: def login(username, password): """ 此函数需要用户名,密码两个参数,完成的是登录的功能. :return: T ...
- 软工网络15团队作业8——Beta阶段敏捷冲刺
Deadline: 2018-5-31 22:00PM,以博客提交至班级博客时间为准 根据以下要求: (1)在敏捷冲刺前发布一篇博客,作为beta版敏捷冲刺的开始, (2)同时,团队在日期区间[5.2 ...
- 学习docker——命令总结
安装docker的方法可以参考:Ubuntu.CentOS.Windows.MacOS 查看版本信息 → ~ $ docker --version Docker version 18.03.1-ce, ...
- semantic-ui 按钮
1.基础按钮: 使用button.div.span.i等标签,将其class设置为"ui button",显示的就是最基础的按钮样式. <i class="ui b ...
- 简要了解 MySql 5.5/5.6/5.7/8 出现的新特性
MySQL的开发周期 在比较之前,首先提一下MySQL的开发周期. MySQL一个大版本的开发,大致经历如下几个阶段: Feature Development Feature Testing Perf ...
- Linux 查找文件命令 find whereis locate
Linux 有三个查找文件的命令:find, whereis, locate 其中find 不常用,whereis与locate经常使用,因为find命令速度较慢,因为whereis与locate是利 ...
- [转帖]Runtime, Engine, VM 的区别是什么?
这就是个WiFi和WLAN关系的问题嘛.Runtime是指用于支持程序运行时的组件,它可以是个Engine和/或VM.VM是一种系统抽象,它提供代码执行所需的API环境.Engine是一种处理抽象,它 ...
- CLOUD常用表
采购采购订单(t_PUR_POOrder, t_PUR_POOrderEntry)-收料通知单(T_PUR_Receive,T_PUR_ReceiveEntry)-采购入库单(T_STK_INSTOC ...
- C# Note18: 使用wpf制作about dialog(关于对话框)
前言 基本上任何software或application都会在help菜单中,有着一个关于对话框,介绍产品的版权.版本等信息,还有就是对第三方的引用(add author credits). 首先,看 ...