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算法求最大生成树的过程.于是我 ...
随机推荐
- luogu P2765 魔术球问题 (最小路径覆盖)
大意:给定n根柱子, 依次放入1,2,3,...的球, 同一根柱子相邻两个球和为完全平方数, 求最多放多少个球. 对和为平方数的点连边, 就相当于求DAG上最小路径覆盖. #include <i ...
- Linux更改ext4根目录文件系统大小
首先通过lsblk 查看一下文件系统情况 然后通过fdisk /dev/sda类似命令,打开对应的磁盘管理,然后: 删除所有磁盘分区 重新建立一个更大的分区. 保存退出 再次通过lsblk查看分区大小 ...
- 【js】面向对象学习资料
1.面向对象模式: https://m.jb51.net/article/74549.htm 2.面向对象基础篇 http://www.cnblogs.com/chiangchou/p/js-oop1 ...
- java面试5
1.如何将String类型转化Number类型?列举说明String str = "123"; Integer num1 = new Integer(str); int num ...
- 在javascript中:(函数()()是一个匿名函数
在javascript中:(函数()()是一个匿名函数,它主要使用函数中的变量范围来避免全局变量,影响整个页面环境,并提高代码兼容性. (函数())是标准函数定义,但不会复制到任何变量.所以有一个没有 ...
- golang 环境变量讲解
以下配置以MAC 下配置为例,但其他环境下大同小异. GOROOT就是go的安装路径在~/.bash_profile中添加下面语句: GOROOT=/usr/local/go export GOROO ...
- 分布式缓存系统 Memcached 快速入门
Memcached介绍 官网地址 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提 ...
- golang实现RSA加密解密
非对称加密示意图: 在此可以看到,非对称加密是通过两个密钥(公钥-私钥)来实现对数据的加密和解密的.公钥用于加密,私钥用于解密. RSA公钥和私钥生成: package main import ( & ...
- php判断
<?php $str = '我是张三?'; preg_match("/张三/", $str, $match); if($match) { echo ' 张三在文本中'; } ...
- SQL 语句 连接
SQL连接可以分为内连接.外连接.交叉连接. 数据库数据: book表 stu表 1.内连接 ...