如果用暴力算法的话,那么会直接超时,我们要学会用并查集去记录下一个空闲的位置
#include<bits/stdc++.h>
using namespace std;
const int N = 100005;
int n;
int fa[N];
int a[N];
int find(int x) {
if (fa[x] == x) {
return x;
}
fa[x] = find(fa[x]);
return fa[x];
}
void ini() {
for (int i = 0; i < N; i++) {
fa[i] = i;
}
}
int main() {
int ans = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
ini();
for (int i = 1; i <= n; i++) {
int p = find(a[i]);
if (p == a[i]) { // 如果空闲位置和当前是一样的
fa[p] = find(p + 1); // 指向下一个空闲位置
}
else {
// 不是一样的说明有重复
ans += p - a[i];
a[i] = p; // 更新数量
fa[p] = find(p + 1);
}
}
//cout << ans << endl;
for (int i = 1; i <= n; i++) {
cout << a[i] << " ";
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
const int N = 200005;
#define int long long
int n;
int fa[N];
int a[200005];
int find(int x) {
if (fa[x] == x) {
return x;
}
fa[x] = find(fa[x]);
return fa[x];
}
void ini() {
for (int i = 0; i < N; i++) {
fa[i] = i;
}
}
signed main() {
int ans = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
ini();
for (int i = 1; i <= n; i++) {
int p = find(a[i]);
if (p == a[i]) { // 如果空闲位置和当前是一样的
fa[p] = find(p + 1); // 指向下一个空闲位置
}
else {
// 不是一样的说明有重复
ans += p - a[i];
a[i] = p; // 更新数量
fa[p] = find(p + 1);
}
}
cout << ans << endl;
for (int i = 1; i <= n; i++) {
cout << a[i] << " ";
}
return 0;
}
我们还可以换
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=200005;
ll a[N]={0},b[N]={0},n,t,ans=0;
map<int,int> fa;
int find(int i){
if(!fa.count(i)) return i;
else return fa[i]=find(fa[i]);
}
int main(){
scanf("%lld",&n);
for(int i=0;i<n;i++){
scanf("%lld",&a[i]);
}
for(int i=0;i<n;i++){
t=find(a[i]);
fa[t]=t+1;
ans+=t-a[i];
a[i]=t;
}
printf("%lld\n",ans);
for(int i=0;i<n;i++) printf("%lld ",a[i]);
return 0;
}
这个题目没什么思路,很多次的修改操作,还有可能会有重叠
我们直接从第m次开始,用fa[x]记录下一个空闲的位置,每一个馒头只刷一次颜色
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
typedef long long ll;
int n, m,p,q;
ll fa[N];
ll a[N];
void ini() {
for (int i = 0; i < N; i++) {
fa[i] = i;
}
}
int find(int x) {
if (fa[x] == x) return x;
fa[x] = find(fa[x]);
return fa[x];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m >> p >> q;
ini();
while (m) {
int ll = (m * p + q)%n + 1;
int rr = (m * q + p) % n + 1;
int l = min(ll, rr);
int r = max(ll, rr);
int x = find(l);
while (x <= r) {
a[x] = m;
fa[x] = find(x + 1);
x = find(x);
}
m--;
}
for (int i = 1; i <= n; i++)
cout << a[i] << '\n';
cout << flush;
return 0;
}