2016集训测试赛(二十六)Problem A: bar
Solution
首先审清题意, 这里要求的是子串而不是子序列...
我们考虑用1表示p, -1表示j. 用sum[i]
表示字符串前\(i\)的前缀和. 则我们考虑一个字符串\([L, R]\)有什么要求: \(\forall x \in [L, R]\)满足\(sum[x] \ge sum[L - 1]\).
我们分别从前往后和从后往前求出以每个位置为开头的最长合法子串, 然后扔进树状数组里面查询即可.
至于怎么求以每个位置为开头最长合法子串, 我们考虑用一个单调栈来维护: 从前往后扫每个位置, 假如当前位置的\(sum\)小于栈顶的\(sum\)则弹栈, 并把以栈顶为开头的最长合法子串的末尾设为当前位置的前一位. 弹栈结束后, 插入当前位置即可.
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = (int)1e6, INF = (int)2e9;
int n;
struct record
{
int L, R;
inline int operator <(const record &a) const {return R < a.R;}
}rec[N + 1];
struct segmentTree
{
int mn[N << 2];
inline segmentTree() {memset(mn, 127 ,sizeof(mn));}
void insert(int u, int L, int R, int pos)
{
mn[u] = min(mn[u], pos);
if(L == R) return;
if(pos <= L + R >> 1) insert(u << 1, L, L + R >> 1, pos);
else insert(u << 1 | 1, (L + R >> 1) + 1, R, pos);
}
inline void insert(int pos) {insert(1, 1, n, pos);}
int query(int u, int L, int R, int pos)
{
if(L >= pos) return mn[u];
int mid = L + R >> 1;
if(pos <= mid) return min(query(u << 1, L, L + R >> 1, pos), query(u << 1 | 1, (L + R >> 1) + 1, R, pos));
else return query(u << 1 | 1, (L + R >> 1) + 1, R, pos);
}
inline int query(int pos) {return query(1, 1, n, pos);}
}seg;
struct binaryIndexedTree
{
int mx[N + 1];
inline binaryIndexedTree() {memset(mx, -1, sizeof(mx));}
inline void insert(int pos, int x)
{
for(int i = pos; i <= n; i += i & - i)
mx[i] = max(mx[i], x);
}
inline int query(int pos)
{
int res = -1;
for(int i = pos; i; i -= i & - i) res = max(res, mx[i]);
return res;
}
}BIT;
int main()
{
#ifndef ONLINE_JUDGE
freopen("bar.in", "r", stdin);
freopen("bar.out", "w", stdout);
#endif
scanf("%d\n", &n);
static int a[N + 1];
for (int i = 1; i <= n; ++ i) a[i] = getchar() == 'p' ? 1 : -1;
static int stk[N + 1], sum[N + 2];
int tp = 0; stk[tp ++] = 0;
sum[0] = 0; for (int i = 1; i <= n; ++ i) sum[i] = sum[i - 1] + a[i]; sum[n + 1] = - INF;
static int f[N + 1];
for (int i = 1; i <= n + 1; ++ i)
{
while (tp && sum[i] < sum[stk[tp - 1]]) f[stk[tp - 1] + 1] = i - 1, -- tp;
stk[tp ++] = i;
}
for(int i = 1; i <= n; ++ i) rec[i].L = i, rec[i].R = f[i];
tp = 0; stk[tp ++] = n + 1;
sum[n + 1] = 0; for(int i = n; i; -- i) sum[i] = sum[i + 1] + a[i]; sum[0] = - INF;
for(int i = n; ~ i; -- i)
{
while(tp && sum[i] < sum[stk[tp - 1]]) f[stk[tp - 1] - 1] = i + 1, -- tp;
stk[tp ++] = i;
}
sort(rec, rec + n + 1);
int ans = 0;
/* for(int i = 1, p = 1; i <= n; ++ i)
{
for(; rec[p].R <= i; ++ p) seg.insert(rec[p].L);
int cur = seg.query(f[i]);
if(cur > i) continue;
else ans = max(ans, i - cur + 1);
} */
for(int i = 1, p = 1; i <= n; ++ i)
{
for(; p <= rec[i].R; ++ p) BIT.insert(f[p], p);
int cur = BIT.query(rec[i].L);
if(cur >= rec[i].L) ans = max(ans, cur - rec[i].L + 1);
}
printf("%d\n", ans);
}
2016集训测试赛(二十六)Problem A: bar的更多相关文章
- 2016北京集训测试赛(十六)Problem C: ball
Solution 这是一道好题. 考虑球体的体积是怎么计算的: 我们令\(f_k(r)\)表示\(x\)维单位球的体积, 则 \[ f_k(1) = \int_{-1}^1 f_{k - 1}(\sq ...
- 2016北京集训测试赛(十六)Problem B: river
Solution 这题实际上并不是构造题, 而是一道网络流. 我们考虑题目要求的一条路径应该是什么样子的: 它是一个环, 并且满足每个点有且仅有一条出边, 一条入边, 同时这两条边的权值还必须不一样. ...
- 2016北京集训测试赛(十六)Problem A: 任务安排
Solution 这道题告诉我们, 不能看着数据范围来推测正解的时间复杂度. 事实证明, 只要常数足够小, \(5 \times 10^6\)也是可以跑\(O(n \log n)\)算法的!!! 这道 ...
- 【2016北京集训测试赛(十六)】 River (最大流)
Description Special Judge Hint 注意是全程不能经过两个相同的景点,并且一天的开始和结束不能用同样的交通方式. 题解 题目大意:给定两组点,每组有$n$个点,有若干条跨组 ...
- 2016集训测试赛(十九)Problem C: 无聊的字符串
Solution 傻X题 我的方法是建立后缀后缀树, 然后在DFS序列上直接二分即可. 关键在于如何得到后缀树上每个字符对应的字节点: 我们要在后缀自动机上记录每个点在后缀树上对应的字母. 考虑如何实 ...
- 2016集训测试赛(十九)Problem A: 24点大师
Solution 这到题目有意思. 首先题目描述给我们提供了一种非常管用的模型. 按照题目的方法, 我们可以轻松用暴力解决20+的问题; 关键在于如何构造更大的情况: 我们发现 \[ [(n + n) ...
- 2016集训测试赛(十八)Problem C: 集串雷 既分数规划学习笔记
Solution 分数规划经典题. 话说我怎么老是忘记分数规划怎么做呀... 所以这里就大概写一下分数规划咯: 分数规划解决的是这样一类问题: 有\(a_1, a_2 ... a_n\)和\(b_1, ...
- 2016北京集训测试赛(十)Problem A: azelso
Solution 我们把遇到一个旗子或者是遇到一个敌人称为一个事件. 这一题思路的巧妙之处在于我们要用\(f[i]\)表示从\(i\)这个事件一直走到终点这段路程中, \(i\)到\(i + 1\)这 ...
- 2018.7.31 Noip2018模拟测试赛(十六)
日期: 七月最后一天 总分: 300分 难度: 提高 ~ 省选 得分: 30分(少的可怜) 我太弱了:(题目目录) T1:Mushroom追妹纸 T2:抵制克苏恩 T3:美味 失分分析:(QA ...
随机推荐
- 1568: [JSOI2008]Blue Mary开公司(超哥线段树)
1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 1198 Solved: 418 Descr ...
- TCP/IP网络编程之多进程服务端(一)
进程概念及应用 我们知道,监听套接字会有一个等待队列,里面存放着不同客户端的连接请求,如果有一百个客户端,每个客户端的请求处理是0.5s,第一个客户端当然不会不满,但第一百个客户端就会有相当大的意见了 ...
- 排查和处理一台被攻击的linux系统及其事后分析
11:40 2018/3/16 发现最近几天服务器流量异常的大,检查了系统命令发现命令最近的修改时间很近,检查dns配置也发现了异常的dns服务器地址. 考虑到事态的严重性,铲掉这个系统重新搭建. 事 ...
- Leetcode 500.键盘行
键盘行 给定一个单词列表,只返回可以使用在键盘同一行的字母打印出来的单词.键盘如下图所示. 示例: 输入: ["Hello", "Alaska", " ...
- Solr linux安装
1.下载安装(自行官网下载) 2.解压安装包 3.进入解压后的bin目录执行命令: ./solr start 出现如下警告: 根据提示修改solr.in.sh中的SOLR_ULIMIT_CHECKS属 ...
- Ubuntu安装nginx(复制)
gcc.g++依赖库 apt-get install build-essential apt-get install libtool 安装 pcre依赖库(http://www.pcre.org/) ...
- Struts2,get/set 自动获取/设置数据ActionSupport 类
主页:http://struts.apache.org/在用户请求和模块化处理方面以及页面的展现这块,Struts2 发挥了强大的作用:相对于传统的Jsp+Servlet 模式,Struts2 更适合 ...
- 【bzoj3280】小R的烦恼 费用流
题目描述 小R最近遇上了大麻烦,他的程序设计挂科了.于是他只好找程设老师求情.善良的程设老师答应不挂他,但是要求小R帮助他一起解决一个难题. 问题是这样的,程设老师最近要进行一项邪恶的实验来证明P=N ...
- BZOJ2657 [Zjoi2012]旅游(journey) 【树的直径】
题目 到了难得的暑假,为了庆祝小白在数学考试中取得的优异成绩,小蓝决定带小白出去旅游~~ 经过一番抉择,两人决定将T国作为他们的目的地.T国的国土可以用一个凸N边形来表示,N个顶点表示N个入境/出境口 ...
- bzoj1093【ZJOI2007】最大半联通子图
题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1093 sol :一开始理解错题意了QAQ,还莫名其妙写挂了QAQ,调了半天 首先显然一个强联 ...