Description

https://www.luogu.org/problemnew/show/P4143


Solution

先求出后缀数组,考虑一个后缀的每一个前缀,发现名次递减、权值增加,那么它们的图像一定只有一个交点,这个是可以二分的。

现在的问题是如何得到一个子串的名次。首先可以通过∑n−heighti−sai∑n−heighti−sai\sum n-height_i-sa_i求出一个后缀的大于height的前缀排名的区间。至于小于等于height的前缀,我们可以用线段树找到最近的小于该长度的height,再作差求出名次即可。


Code

/************************************************* Au: Hany01* Prob: Platform* Email: hany01@foxmail.com************************************************/#include<bits/stdc++.h>using namespace std;typedef long long LL;
typedef pair<int, int> PII;
#define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i)
#define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define x first
#define y second
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) ((int)(a).size())
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define Mod (1000000007)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define y1 wozenmezhemecaiatemplate <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }inline int read()
{register int _, __; register char c_;for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1;for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);return _ * __;
}const int maxn = 200005;int n, val[maxn], c[maxn], mm, sum[maxn];
char s[maxn];
vector<PII> lst;int rk[maxn << 1], sa[maxn << 1], tp[maxn << 1], height[maxn << 1];
LL rksum[maxn], tot;inline void RadixSort()
{For(i, 1, mm) c[i] = 0;For(i, 1, n) ++ c[rk[i]];For(i, 1, mm) c[i] += c[i - 1];Fordown(i, n, 1) sa[c[rk[tp[i]]] --] = tp[i];
}inline void build(char *s)
{For(i, 1, n) rk[i] = s[i], tp[i] = i;mm = 300, RadixSort();for (register int k = 1, p; k <= n; k <<= 1) {p = 0;For(i, n - k + 1, n) tp[++ p] = i;For(i, 1, n) if (sa[i] > k) tp[++ p] = sa[i] - k;RadixSort(), swap(rk, tp), rk[sa[1]] = 1, mm = 1;For(i, 2, n) rk[sa[i]] = tp[sa[i - 1]] == tp[sa[i]] && tp[sa[i] + k] == tp[sa[i - 1] + k] ? mm : ++ mm;if (mm == n) break;}for (int i = 1, j, k = 0; i <= n; height[rk[i ++]] = k)for (k = k ? k - 1 : 0, j = sa[rk[i] - 1]; s[i + k] == s[j + k]; ++ k) ;
}inline void calc() {For(i, 1, n) rksum[i] = rksum[i - 1] + n + 1 - height[i] - sa[i];
}struct SegmentTree //Maintain the minimum
{int tr[maxn << 2];
#define lc (t << 1)
#define rc (lc | 1)
#define mid ((l + r) >> 1)void build(int t, int l, int r) {if (l == r) tr[t] = height[l];else build(lc, l, mid), build(rc, mid + 1, r), tr[t] = min(tr[lc], tr[rc]);}int query(int t, int l, int r, int x, int y, int v){if (l == r) return tr[t] < v ? l : 1;if (x > mid) return query(rc, mid + 1, r, x, y, v);if (y <= mid) return query(lc, l, mid, x, y, v);int tmp;if (tr[rc] >= v) return query(lc, l, mid, x, y, v);if ((tmp = query(rc, mid + 1, r, x, y, v)) != 1) return tmp;return query(lc, l, mid, x, y, v);}
#undef mid
}ST;inline LL check(int l, int r) //Return the rank minus the value
{register int pos = rk[l], p = ST.query(1, 1, n, 1, pos, r - l + 1), len = r - l + 1, st, ed1, ed2, real = sa[p] + len - 1;ed1 = (st = sa[p]) + height[p], ed2 = n;register LL Rk = rksum[p - 1] + real - ed1 + 1;return (tot - Rk + 1) - (sum[r] - sum[l - 1]);
}inline int solve()
{calc(), ST.build(1, 1, n);tot = rksum[n];int Ans = 0, st, ed1, ed2, now = 0, l, r, mid;For(i, 1, n){st = sa[i], l = st, r = n;while (l < r) {mid = (l + r) >> 1;if (check(st, mid) > 0) l = mid + 1; else r = mid;}if (!check(st, l)) ++ Ans, lst.pb(mp(st, l));}return Ans;
}int main()
{File("platform");scanf("%s", s + 1), n = strlen(s + 1), build(s);For(i, 1, n) sum[i] = sum[i - 1] + (val[i] = read());printf("%d\n", solve());sort(ALL(lst));rep(i, SZ(lst)) printf("%d %d\n", lst[i].x, lst[i].y);return 0;
}
//寂寞空庭春欲晚,梨花满地不开门。
//    -- 刘方平《春怨》

【BZOJ5405】platform(二分,SA,线段树)相关推荐

  1. 猜数(二分、线段树)

    题目描述 对于一个长度为n的数列给出m个描述 每一个描述给出一个区间[a,b]的最小值的x 求从第几个描述开始矛盾 解析 本题关键是一个关于矛盾的充要条件: 如果存在一个最小值x,其所在的区间的交集( ...

  2. YbtOJ#463-序列划分【二分答案,线段树,dp】

    正题 题目链接:https://www.ybtoj.com.cn/problem/463 题目大意 给出长度为nnn的序列A,BA,BA,B.要求划分成若干段满足 对于任何i<ji<ji& ...

  3. 【BZOJ3958】[WF2011]Mummy Madness 二分+扫描线+线段树

    [BZOJ3958][WF2011]Mummy Madness Description 在2011年ACM-ICPC World Finals上的一次游览中,你碰到了一个埃及古墓. 不幸的是,你打开了 ...

  4. 【TJOI2016】【bzoj4552】排序(二分答案+线段树01排序)

    problem 给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序 排序分为两种 1:(0,l,r)表示将区间[l,r]的数字升序排序 2:(1,l,r)表示将区间[l,r]的数字降序排序 ...

  5. 线段树 ---- 线段树上区间二分 或者单点二分 codeforces C. Greedy Shopping

    题目大意 题目大意: 给你一个非增的区间现在你有两次操作 1 x y : 把[a1,...ax][a_1,...a_x][a1​,...ax​]里面的数对yyy取maxmaxmax 2 x y : 你 ...

  6. 【题解】 [HEOI2016]排序题解 (二分答案,线段树)

    题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行 ...

  7. A Simple Problem with Integers POJ - 3468(线段树+区间查询+区间修改+建树+懒惰标记模板)+(树状数组)

    题意: 有一个数组,有两种操作.1: Q a b 求[a,b]的和 2:C a b c 给[a,b] 的所有元素都加上c. 题目: You have N integers, A1, A2, ... , ...

  8. hdu 4747 mex 线段树+思维

    http://acm.hdu.edu.cn/showproblem.php?pid=4747 题意: 我们定义mex(l,r)表示一个序列a[l]....a[r]中没有出现过得最小的非负整数, 然后我 ...

  9. 线段树简单入门 (含普通线段树, zkw线段树, 主席树)

    线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...

  10. 线段树 --算法竞赛专题解析(24)

    本系列文章将于2021年整理出版.前驱教材:<算法竞赛入门到进阶> 清华大学出版社 网购:京东 当当   作者签名书:点我 有建议请加QQ 群:567554289 文章目录 1. 线段树概 ...

最新文章

  1. 从Asp.net转到Php之调试
  2. 2015年3月-前端开发月刊
  3. c++面试题之标准模板库
  4. SpringMVC总结三:请求Controller返回视图类型以及请求方式、参数介绍
  5. Windows Server 2012 RS 配置IIS8.0+发布网站
  6. Xvid编码器流程(基于xvid1.1.0)
  7. jzoj3783-[NOIP2014模拟8.19]签到题【结论题】
  8. h5评论直接显示代码_全套H5教程免费学,让你0基础自学制作H5页面
  9. 低功耗电波钟的制作 - 电子设计竞赛
  10. 合同法律风险管理 被骗者刑事风险
  11. Java将PDF转换成图片
  12. win10笔记本,蓝牙耳机连接上电脑以后,耳机没有声音怎么办?
  13. Pseudo-伪标签
  14. 让自己更优秀的 16 条法则(建议收藏)
  15. 如何确定抽样的样本数量
  16. Vi下编辑和退出编辑方法
  17. fts touchscreen
  18. 26岁从计算机视觉界“黄埔军校”博士毕业,他想为车打造一双慧眼
  19. 数据存储策略——lsm-tree
  20. 事业单位高级工计算机操作员,事业单位高级工可以拿到多少工资?

热门文章

  1. 图像识别,ocr 技术,有兴趣的可以了解一下
  2. 数字三角形求最大路径
  3. linux下显卡信息的查看
  4. 向量大小和归一化(vector magnitude normalization)、向量范数(vector norm)、标量/向量/矩阵/张量
  5. 金蝶EAS,查询分析器,分页查询,获取6500行之后的记录
  6. MYSQL 唯一约束
  7. PHP MVC框架初探
  8. Python 音频随机播放器脚本
  9. android 关机闹钟 实现,android 关机闹钟
  10. WORD禁止自动更新域