LOJ #2734 Luogu P3615 [JOI2016春季合宿]Toilets (结论、贪心)
题目链接
(loj) https://loj.ac/problem/2734
(luogu) https://www.luogu.org/problem/P3615
题解
嗯,考场上肝了$3h$然而最后发现一个智障地方没想到……我果然还是菜的真实啊
首先队列合法(能在$N$分钟内解决)当且仅当: 每一个长度为偶数的后缀女生数量都不少于一半(一个等价的表述是,如果把男人看成$1$女人看成$-1$那么任何一个后缀和不大于$1$, 但是这里由于是对女生操作所以只考虑女生会好很多)。证明只能根据题意一步步推,这里略去。
然后考虑$O(n)$做法: 若总共男人数严格多于女人数则无解,否则从后往前扫,若某个后缀女人数量少于一半了就把最近的女人移过来,显然最优。
因此,设从后往前第$i$个女人位于从后往前第$i$个位置,则答案为$\max(0,\max_i (b_i-2i))$.
现在字符串长度很大,那么发现对于每一个重复的子串,若其中女人数量多于一半则只需考虑从后往前的第一次重复,否则只需考虑最后一次,于是直接做即可。
时间复杂度$O(\sum |s_i|)$.
代码
#include<bits/stdc++.h>
#define llong long long
#define mkpr make_pair
using namespace std;
const int N = 2e5;
struct Element
{
vector<char> s;
int cnt0,cnt1; llong t;
} a[N+3];
llong sum[N+3],sum1[N+3];
char str[N+3];
llong n; int m;
int main()
{
scanf("%lld",&n);
scanf("%d",&m);
llong tot = 0ll;
for(int i=1; i<=m; i++)
{
scanf("%s%lld",str+1,&a[i].t); int len = strlen(str+1);
for(int j=1; j<=len; j++)
{
a[i].s.push_back(str[j]);
if(str[j]=='F') {tot-=a[i].t; a[i].cnt1++;}
else {tot+=a[i].t; a[i].cnt0++;}
}
}
for(int i=m; i>=1; i--)
{
sum[i] = sum[i+1]+a[i].s.size()*a[i].t;
sum1[i] = sum1[i+1]+a[i].cnt1*a[i].t;
}
if(tot>0) {puts("-1"); return 0;}
llong ans = 0ll;
for(int i=m; i>=1; i--)
{
llong cur1 = sum1[i+1],cur = sum[i+1];
if(2*a[i].cnt1<a[i].s.size())
{
cur1 += a[i].cnt1*(a[i].t-1ll);
cur += a[i].s.size()*(a[i].t-1ll);
}
for(int j=a[i].s.size()-1; j>=0; j--)
{
cur++;
if(a[i].s[j]=='F') {cur1++;}
// printf("cur=%lld cur1=%lld\n",cur,cur1);
ans = max(ans,cur-(cur1<<1)-1);
}
}
printf("%lld\n",ans);
return 0;
}
LOJ #2734 Luogu P3615 [JOI2016春季合宿]Toilets (结论、贪心)的更多相关文章
- LOJ #2731 [JOI2016春季合宿]Solitaire (DP、组合计数)
题目链接 https://loj.ac/problem/2731 题解 首先一个很自然的思路是,设\(dp[i][j]\)表示选了前\(i\)列,第\(2\)行第\(i\)列的格子是第\(j\)个被填 ...
- LOJ #2733 [JOI2016春季合宿]Sandwiches (DP)
题目链接 https://loj.ac/problem/2733 题解 神仙题-- 首先可以观察到一个结论: 目标块的两块小三明治一定分别是最后和倒数第二个被吃的. 由此我们可以考虑这两块谁先被吃.这 ...
- JOI2017 春季合宿:Railway Trip
自己的AC做法似乎离正解偏了十万八千里而且复杂了不少--不管怎样还是记录下来吧. 题意: 题目链接: JOISC2017 F - AtCoder JOISC2017 F - LOJ \(N\)个车站排 ...
- UOJ356 [JOI2017春季合宿] Port Facility 【启发式合并】【堆】【并查集】
题目分析: 好像跑得很快,似乎我是第一个启发式合并的. 把玩具看成区间.首先很显然如果有两个玩具的进出时间有$l1<l2<r1<r2$的关系,那么这两个玩具一定在不同的栈中间. 现在 ...
- [JOI2017春季合宿]Port Facility[set、二分图]
题意 你有两个栈,有 \(n\) 个货物,每个货物有一个进栈时间和出栈时间(所有时间的并集是1~2n),问有多少种不同的入栈方案. \(n\le 10^6\) 分析 把每个货物的存在看成区间,相交的区 ...
- UOJ #356. 【JOI2017春季合宿】Port Facility
Description 小M有两个本质不同的栈. 无聊的小M找来了n个玩具.之后小M把这n个玩具随机顺序加入某一个栈或把他们弹出. 现在小M告诉你每个玩具的入栈和出栈时间,现在她想考考小S,有多少种方 ...
- UOJ #357. 【JOI2017春季合宿】Sparklers
Description 小S和小M去看花火大会. 一共有 n 个人按顺序排成一排,每个人手上有一个仅能被点燃一次的烟花.最开始时第 K 个人手上的烟花是点燃的. 烟花最多能燃烧 T 时间.每当两个人的 ...
- UOJ356 【JOI2017春季合宿】Port Facility
暴力就是O(n^2)连边,二分图,这样只有22分. 我们考虑优化建边,我们按照左端点排序,对于一个新加进来的线段,我们向左端点距其最近的和他相交的线段连边,别的相交的我们连同色边,当一个点连了两条同色 ...
- BZOJ 4388 [JOI2012春季合宿]Invitation (线段树、二叉堆、最小生成树)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4388 题解 模拟Prim算法? 原题所述的过程就是Prim算法求最大生成树的过程.于是我 ...
随机推荐
- mysql 8.x 登陆提示 Access denied for user 'root'@'localhost' (using password: YES)
第一步:修改 /etc/mysql/my.cnf. 在[mysql]下添加skip-grant-table:重启. 第二步:通过mysql命令登陆: flush privileges; use mys ...
- json在线格式化校验
推荐个在线工具箱,json在线格式化转换编码,挺好用的 https://www.codejson.com/
- 【JavaScript】js中的call方法
moziila官方文档链接:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Funct ...
- 使用脚本启动fabric时出错
Error: got unexpected status: BAD_REQUEST -- error authorizing update: error validating ReadSet: rea ...
- Delphi Android拍照报错
打开拍照提示以上错误,解决方式
- centos8下jdk13和tomcat9的安装
首先下载JDK13和tomcat9在对应的官网上: 通过xftp传到linux服务器上的对应的目录,如/usr/local apache-tomcat-9.0.27.tar.gz ,jdk-13.0 ...
- 【Day2】2.函数
视频地址(全部) https://edu.csdn.net/course/detail/26057 课件地址(全部) https://download.csdn.net/download/gentl ...
- java指定运行jar包中的其中一个main方法
java -cp jar包 类名 java -cp ******.jar com.******.EsEtl
- KeyError: 'pass_ticket'
使用wxpy模块对接微信登陆,在扫描程序弹出二维码后,使用手机微信扫描登陆之后报KeyError: 'pass_ticket'. 原因就是微信禁止该账号登陆微信网页版,如下图: 所以,去找到能让账号登 ...
- 使用Task的Wait和Result时注意
如果计算限制的任务抛出未处理的异常,该异常会被“吞噬”并存储到一个集合中,而线程池线程可以返回到线程池中.调用Wait方法或者Result属性时,这些成员会抛出一个System.AggregateEx ...