为了能到远方,脚下的每一步都不能少.|

vanueber

园龄:2年6个月粉丝:0关注:2

P10995 【MX-J3-T2】Substring 解题报告

P10995 【MX-J3-T2】Substring

也是在赛时做出黄题了(后话:现在降 力,后话的后话:现在又升 了)。

首先考虑暴力求出所有字串,排序一遍,时间复杂度 O(n2) ,预期得分 45pts

思考如何不求出所有字串就可以查询出第 k 个字串。以样例为例。

3 6
3 1 2
1
2
3
4
5
6

答案:

2 2
2 3
3 3
1 1
1 2
1 3

观察到数字 1 开头的字串一定大于其他数字开头的字串(证明:根据字典序定义显然),而根据序列性质: 其中 1∼n 各出现了一次 ,数字 1 开头的子串越长排名越大。具体地 [1]<[1,2] ,于是根据数字在原数组中的位置,可以求出以数字 x 开头的子串数量,并且它们的排名也因此确定了

解释:令 Sx 代表以 x 开头的子串的集合,那么显然有 S1<S2<S3<...<Sn (这里比较每个集合内子串字典序大小)。
并且每个Sx 内的排名也是确定且与子串大小相关(如以 3 开头,长度为 2 的子串的排名就是以 3 开头长度为 1 的字串的排名 +1,注意这里以 x 开头长度为 1 的字串排名是可以预处理出来的)。

接下来看具体实现:

posi 表示第数字 i 在原数组出现位置。

leni 表示以数字 i 开头的子串长度。

prelen 的前缀和,prei 也就表示以 i 开头,长度为 1 的子串的排名。

于是对于每个查询 k ,二分求出其子串开头是什么,然后整个区间根据已知信息,手推一遍样例也就出来了。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
#define int long long
using namespace std;

const int maxn = 3e5 + 5;
int n, q, k;
int a[maxn];
map<int, int> pos;
int len[maxn], pre[maxn];

signed main()
{
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
#endif
	cin >> n >> q;
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &a[i]);
		pos[a[i]] = i;
	}
	for (int i = 1, num; i <= n; i++)
	{
		num = pos[i];
		len[i] = n - num + 1;
	}
//	for (int i = 1; i <= n; i++) {
//		cout << len[i];
//	}
//	cout << endl;
	for (int i = 2; i <= n + 1; i++)
	{
		pre[i] = pre[i - 1] + len[i - 1];
	}
//	for (int i = 1; i <= n + 1; i++) {
//		cout << pre[i] << " ";
//	}
//	cout << endl;
	while (q--)
	{
		scanf("%lld", &k);
//		cout << k << " ";
		int x = lower_bound(pre + 1, pre + n + 2, k) - pre - 1;
//		cout << x << "# ";
		if (x == n + 1)
		{
			cout << pos[n] << " " << pos[n] + len[n] - 1 << endl;
		}
		else
		{

			if (k == pre[x])
			{
				cout << pos[x] << " " << pos[x] + k - pre[x] << endl;
			}
			else
			{
				cout << pos[x] << " " << pos[x] + k - pre[x] - 1 << endl;
			}
		}
	}
	return 0;
}

本文作者:vanueber

本文链接:https://www.cnblogs.com/vanueber/p/18668588

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   vanueber  阅读(1)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起