题目大意:
有N块积木,每一块积木都有自己的颜色以及数字,这N块积木颜色的范围从1到M,有k次操作,每次操作可以把一种颜色换成另外一种颜色,相邻而相同颜色的积木可以互换位置,求每次染色操作后所能排列的积木的最大数字。
思路分析:
对于染色前的操作,只需要把不同颜色的积木进行标记,并把每段相同颜色的积木上的数字排序后即可得到最大的数字。
因此我们可以开一个数组记录原始积木的数字,在另外开一个数组记录相应的颜色,每种颜色的下标对于其相应颜色的下标。之后只需要对颜色的数组进行切段并记录下其相应的下标的位置,之后对数字数组相应的部分进行排序之后输出即可。
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#define INF 0x3f3f3f
#define ll long long
#define fre() freopen(".in", "r", stdin);freopen(".out", "w", stdout);
using namespace std;
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
const double eps = 1e-6;
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
int col[N];
char s[N];
int n, m, k;
ll max_num()
{
for (int l = 1, r = 1; l <= n; l = r + 1, r = l)//数组分区切段
{
while (r < n && (col[l] == col[r + 1]))r++;
sort(s + l, s + r + 1, [](const char &a, const char &b)//对切段的数组进行排序
{
return a > b;
});
}
ll sum = 0;
for (int i = 1; i <= n; i++)//将字符串转换为整数
{
sum = sum * 10 + (s[i] - '0');
sum %= mod;
}
return sum;
}
void s_col(int x, int y)//变更颜色
{
for (int i = 1; i <= n; i++)
{
if (col[i] == x)
col[i] = y;
}
return ;
}
int main()
{
n = read();
m = read();
k = read();
scanf("%s", s + 1);
for (int i = 1; i <= n; i++)col[i] = read();
cout << max_num() << endl;
while (k--)
{
int p, q;
p = read();
q = read();
s_col(p, q);
cout << max_num() << endl;
}
return 0;
}