2020牛客暑期多校训练营(第一场)

A B-Suffix Array

题意;

将字符串 s s 的每个后缀化成 B B 数组,然后对 B B 数组进行字典序排序。
那个定义的规则就是找前面和他相同字符的最近距离,否则为 0 0

c i c_i 相当于后面的最近的与 s i s_i 相同的字符到 i i 的距离。

对于不存在这样的 j j c i c_i ,我们要让他比其他 c i c_i 都大,设为 c i = n c_i=n ,然后最后再放一个 n + 1 n+1 c c 的末尾,最后求出 c c 的后缀数组,去掉最后一位倒着输出就是答案。
在这里插入图片描述
在这里插入图片描述

AC代码:

const int N = 1e5 + 50;
int n, s[N];
char S[N];
int fir[N], sec[N], sa[N], c[N];
void get_SA()
{
	int m = n;
	rep(i, 1, n)
		c[fir[i] = s[i]]++;
	rep(i, 2, m)
		c[i] += c[i - 1];
	per(i, n, 1)
		sa[c[fir[i]]--] = i;
	for (int k = 1, tot; k < n; k <<= 1)
	{
		tot = 0;
		rep(i, n - k + 1, n)
			sec[++tot] = i;
		rep(i, 1, n) if (sa[i] > k)
			sec[++tot] = sa[i] - k;
		rep(i, 1, m)
			c[i] = 0;
		rep(i, 1, n)
			c[fir[i]]++;
		rep(i, 2, m)
			c[i] += c[i - 1];
		per(i, n, 1)
			sa[c[fir[sec[i]]]--] = sec[i];
		rep(i, 1, n)
			swap(fir[i], sec[i]);
		fir[sa[1]] = tot = 1;
		rep(i, 2, n) if (sec[sa[i]] == sec[sa[i - 1]] && sec[sa[i] + k] == sec[sa[i - 1] + k])
			fir[sa[i]] = tot;
		else fir[sa[i]] = ++tot;
		if (tot == n)
			break;
		m = tot;
	}
}

int main()
{
	while (~sd(n))
	{
		ss(S + 1);
		rep(i, 1, n)
		{
			rep(j, i + 1, n)
			{
				if (S[j] == S[i])
				{
					s[i] = j - i;
					break;
				}
			}
			if (!s[i])
				s[i] = n;
		}
		n++;
		s[n] = n;
		get_SA();
		per(i, n - 1, 1)
			printf("%d ", sa[i]);
		printf("\n");
		rep(i, 1, n)
			s[i] = fir[i] = sec[i] = sa[i] = c[i] = 0;
	}
}

F Infinite String Comparision

题意:

给定两个字符串 a b a,b 。比较无限个字符串 a a 拼接和无限个字符串 b b 拼接的大小。

先把长的串复制两次,然后把短的串变成复制或长串的长度直接比较就行了。

AC代码:

const int N = 1e6 + 50;
int n, m, k, x;
string a, b;
int main()
{
	int t;
	while (cin >> a >> b)
	{
		int len1 = a.size();
		int len2 = b.size();
		if (len1 == len2)
		{
			if (a == b)
				puts("=");
			else if (a < b)
				puts("<");
			else
				puts(">");
		}
		else if (len1 < len2)
		{
			b += b;
			len2 += len2;
			string s = a;
			int len = len1;
			while (len + len1 <= len2)
			{
				s += a;
				len += len1;
			}
			if (len < len2)
			{
				int res = len2 - len;
				rep(i, 0, res - 1)
					s += a[i];
			}
			//cout<<s<<endl;
			//cout<<b<<endl;
			if (s == b)
				puts("=");
			else if (s < b)
				puts("<");
			else
				puts(">");
		}
		else
		{
			a += a;
			len1 += len1;
			string s = b;
			int len = len2;
			while (len + len2 <= len1)
			{
				s += b;
				len += len2;
			}
			if (len < len1)
			{
				int res = len1 - len;
				rep(i, 0, res - 1)
					s += b[i];
			}
			//cout<<a<<endl;
			//cout<<s<<endl;
			if (s == a)
				puts("=");
			else if (s < a)
				puts(">");
			else
				puts("<");
		}
	}
	return 0;
}

J Easy Integration

题意;

给定一个 n n ,求 0 1 ( x x 2 ) n d x \int_{0}^{1} (x-x^2)^n dx 约分后的答案。

= 0 1 x n ( 1 x ) n d x =\int_{0}^{1}x^n*(1-x)^ndx

= x n + 1 n + 1 0 1 + 0 1 x n + 1 n + 1 n ( 1 x ) n 1 d x =\frac{x^{n+1}}{n+1}|_0^1+\int_{0}^{1}\frac{x^{n+1}}{n+1}*n*(1-x)^{n-1}dx

= n n + 1 0 1 x n + 1 ( 1 x ) n 1 d x =\frac{n}{n+1}\int_{0}^{1}x^{n+1}*(1-x)^{n-1}dx

= n ! ( n + 1 ) ( n + 2 ) . . . ( 2 n ) 0 1 x 2 n d x =\frac{n!}{(n+1)(n+2)...(2n)}*\int_{0}^{1}x^{2n}dx

= n ! 1 2 n + 1 ( n + 1 ) ( n + 2 ) . . . ( 2 n ) =\frac{n!*\frac{1}{2n+1}}{(n+1)(n+2)...(2n)}

= n ! ( n + 1 ) ( n + 2 ) . . . ( 2 n ) ( 2 n + 1 ) =\frac{n!}{(n+1)(n+2)...(2n)(2n+1)}

= n ! 2 ( 2 n + 1 ) =\frac{n!^2}{(2n+1)}

AC代码:

ll mult(ll x, ll y, ll mod)
{
	return (x * y - (ll)(x / (long double)mod * y + 1e-3) * mod + mod) % mod;
}

const int N = 2e6 + 50;
const int mod = 998244353;
int n, m, k, x;
ll f[N];

void init()
{
	f[0] = 0;
	f[1] = 1;
	rep(i, 2, N - 10)
		f[i] = mult(f[i - 1], i, mod);
}

int main()
{
	init();
	while (~sd(n))
	{
		ll ans = mult(qpow(f[n], 2, mod), qpow(f[2 * n + 1], mod - 2, mod), mod);
		pld(ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43627087/article/details/107375919
今日推荐