E、智乃的数字积木(easy version)

按照题意模拟,每次取色相同的一整段进行从大到小排序。

这里萌新需要学习的两个小技巧

数组切段

每年看新生代码的时候尤其是有切字符串或者切数组这种需求的时候,发现新生切串一般都写的贼麻烦,其实这种只用写一个for+一个while语句就可以实现。

for (int l = 1, r = 1; l <= n; l = r + 1, r = l)
{
	while (r < n && (a[l]==a[r+1]) )++r;
    printf("[%d,%d] ",l ,r);
}

lambda

sort需要传排序函数的时候,如果cmp函数没有重复利用的必要,可以使用匿名函数在调用sort函数时直接定义。

比如int数组从大到小进行排序,可以这么写

sort(a + 1, a + 1 + n, [](const int&A, const int&B) {
     return A > B;
});

这样做的好处是在面向过程的编程中,不会破坏编程的连续性,你可以顺着在一个函数过程中直接写,不用在跳出函数外部额外写一个函数,可以增加写代码的速度。

时间复杂度O(NlogN)O(NlogN),空间复杂度O(N)O(N)

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
const long long mod = 1e9 + 7;
int n, m, k,u,v;
int col[MAXN];
char s[MAXN];
long long cal()
{
	for (int l = 1, r = 1; l <= n; l = r + 1, r = l)
	{
		while (r < n && col[r + 1] == col[l])++r;
		sort(s + l, s + 1 + r, [](const char&A, const char&B) {
            return A > B;
        });
	}
	long long ret = 0;
	for (int i = 1; i <= n; ++i)
	{
		ret = ret * 10 + (s[i] - '0');
		ret %= mod;
	}
	return ret;
}
void modify_col(int col_from, int col_to)
{
	for (int i = 1; i <= n; ++i)
	{
		if(col[i]==col_from)col[i]=col_to;
	}
	return;
}
int main()
{
	scanf("%d %d %d", &n, &m, &k);
	scanf("%s", s + 1);
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d", &col[i]);
	}
	printf("%lld\n", cal());
	while (k--)
	{
		scanf("%d %d",&u,&v);
		modify_col(u,v);
		printf("%lld\n", cal());
	}
	return 0;
}