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_JUDGEfreopen("bar.in", "r", stdin);freopen("bar.out", "w", stdout);#endifscanf("%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);
}

转载于:https://www.cnblogs.com/ZeonfaiHo/p/7551888.html

2016集训测试赛(二十六)Problem A: bar相关推荐

  1. 2016集训测试赛(二十四)Problem C: 棋盘控制

    Solution 场上的想法(显然是错的)是这样的: 我们假设棋子是一个一个地放置的, 考虑在放置棋子的过程中可能出现哪些状态. 我们令有序整数对\((i, j)\)表示总共控制了\(i\)行\(j\ ...

  2. 2016集训测试赛(二十四)Problem B: Prz

    Solution 这道题有两个关键点: 如何找到以原串某一个位置为结尾的某个子序列的最晚出现位置 如何找到原串中某个位置之前的所有数字的最晚出现位置中的最大值 第一个关键点: 我们注意到每个数字在\( ...

  3. [补档]noip2019集训测试赛(十二)

    Problem A: 记忆(memory) Time Limit: 1000 ms Memory Limit: 512 MB Description 你在跟朋友玩一个记忆游戏. 朋友首先给你看了n个长 ...

  4. 2016北京集训测试赛(十三) Problem B: 网络战争

    Solution KD tree + 最小割树 转载于:https://www.cnblogs.com/ZeonfaiHo/p/7420354.html

  5. 2016北京集训测试赛(九)Problem C: 狂飙突进的幻想乡

    Solution 我们发现, 对于一条路径来说, 花费总时间为\(ap + q\), 其中\(p\)和\(q\)为定值. 对于每个点, 我们有多条路径可以到达, 因此对于每个区间中的\(a\)我们可以 ...

  6. [补档]noip2019集训测试赛(十五)

    Problem A: 传送带 Time Limit: 1000 ms Memory Limit: 256 MB Description 在一个二维平面上有两条传送带,每一条传送带可以看成是一条线段.两 ...

  7. [补档]noip2019集训测试赛(十)

    Problem A: fibonacci Time Limit: 2000 ms Memory Limit: 256 MB Description 小y最近迷上了fibonacci数列,他定义了一种数 ...

  8. [补档]noip2019集训测试赛(十四)

    Problem A: Fibonacci(fib.pas/cpp) Time Limit: 1000 ms Memory Limit: 128 MB Description 豆豆最近迷上了Fibona ...

  9. 模板方法模式 Template method 行为型 设计模式(二十六)

    模板方法模式 Template method 上图为网上百度的一份简历模板截图 相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为你的 ...

最新文章

  1. OpenGL编程轻松入门(四)
  2. 什么??听说Python要凉!
  3. 关于java中多态的理解,涉及到内存空间
  4. Spring ribbon
  5. 【详细注释】1051 Pop Sequence (25 分)
  6. 政企上云网络适配复杂,看华为云Stack有妙招
  7. 加载类型库/dll时出错 的解决方法
  8. Silverlight网络寻奇 at 090413
  9. hadoop 用MR实现join操作
  10. ios yylabel 加载html,iOS关于YYLabel的富文本点击事件
  11. 宝塔Linux面板如何进入,云服务器怎么进入宝塔面板
  12. 浏览器下载文件的两种方式
  13. 微商怎么引流学生粉?如何把学生粉变现成精准粉?
  14. 明辰智航网络一点通网络性能测试仪可以做什么
  15. TCP/IP协议第一章笔记
  16. AltiumDesigner规则设置
  17. 除了中国知网和谷歌文学还有哪些好的有权威的资源站?
  18. SAP_HCM_Schema_CN28_XIN0
  19. 信号完整性之浅谈理解(七)
  20. 编程语言JAVA和Python如何选择?

热门文章

  1. 收藏 | 超轻量目标检测模型NanoDet,比YOLO跑得快,上线两天Star量超200
  2. 伯克利2019深度学习课程—李沐及其亚马逊同事一起讲述(内附视频链接及PDF下载)
  3. 揭示地理数据分布规律的方法
  4. python sys.path.append()添加路径_Python调用CST进行天线建模仿真:环境搭建指南
  5. php 5.6 mcrypt,php 5.6.36 安装mcrypt
  6. C#-JSON的序列化和反序列化
  7. python的特性是_python的特性
  8. 移动端页面rem+media写法过程
  9. 看《Linux入门讲座》随记
  10. [转帖]win10 .Net Runtime Optimization Service占用大量CPU资源解决方法