CF731D.80-th Level Archeology(暴力)

版权声明:蒟蒻的博文,dalao转载标明出处就好吖 https://blog.csdn.net/jokingcoder/article/details/89437806

为什么这么水一道题没人写呢qwq
传承cy的水博客精神(雾
传送门RuA!

题意

给你一堆字符串(其实是数组?)对每个字符(数) + x +x (超过 c c 就从头开始)
输出任意一个使最后的字符串们字典序非递减的 x x 就好啦!

Solution

要满足整体字典序非递减,那不就是前一个的字典序一定要小于等于当前的字典序咩?
发现两个字符串的相对顺序不会变所以只要找到相邻两个第一个不同的位置(或者说某一个先没有了)
这样我们就可以使前一个字母小于后一个字母所需要的 x x 范围
于是得到 n n 个及以下的区间,最终取一个交集就好惹

(取交集用差分实现?
再随便输一个满足的答案。。。)

Code

#include <cstdio>
#include <iostream>
#include <vector>
#define N 1000010

using namespace std;
int l[N], neq[N];
vector<int> p[N];

inline int read() {
	char ch = getchar();
	int x = 0;
	while (!isdigit(ch)) ch = getchar();
	while (isdigit(ch)) {
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x;
}

int main() {
	int n = read(), c = read();
	for (int i = 1; i <= n; ++i) {
		l[i] = read();
		for (int j = 1; j <= l[i]; ++j) {
			p[i].push_back(read());
		}
	}
	for (int i = 2; i <= n; ++i) {
		int now = 0;
		while (1) {
			if (now >= l[i - 1]) break;//后面比前面长,前面的串是后面这个串的某个前缀,所以一定满足
			if (now >= l[i]) {//前面比后面长,后面的串是前面这个串的某个前缀,所以一定布星
				puts("-1");
				return 0;
			}
			if (p[i - 1][now] > p[i][now]) {//前面的比后面的来得大,前面得轮回而后面不能。
				neq[0]++;
				neq[c - p[i - 1][now] + 1]--;
				neq[c - p[i][now] + 1]++;
				neq[c]--;
				break;
			}
			if (p[i - 1][now] < p[i][now]) {//前面的比后面的来得小,前面和后面一起轮回或一起不轮回。
				neq[c - p[i][now] + 1]++;
				neq[c - p[i - 1][now] + 1]--;
				break;
			}
			now++;
		}
	}
	for (int i = 0; i < c; ++i) {
		if (i) neq[i] += neq[i - 1];
		if (!neq[i]) {
			printf("%d\n", i);
			return 0;
		}
	}
	puts("-1");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jokingcoder/article/details/89437806