专栏文章
题解:P14029 【MX-X20-T3】「FAOI-R7」重排序列(update)
P14029题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minwk9pm
- 此快照首次捕获于
- 2025/12/02 09:31 3 个月前
- 此快照最后确认于
- 2025/12/02 09:31 3 个月前
该做法与第一篇题解略有不同。
已知 ,我们将 序列中所有数对 取模,那么 的值域为 。
理想情况下,对于所有 有 ,那么和为 。但显然我们可能会有某些位置 有 ,此时贡献变成了 。对比理想状况,位置 产生的贡献减少了 , 是给定常数,问题就转化成如何排列使得 的情况最少。
将 降序排序, 升序排序, 在递减过程中, 中满足 的区间会向右扩展,我们不难发现此时 去匹配最小的 是最优的。如果 怎么匹配都匹配不到 ,那就只能去和最大的 匹配,将更小的 留给后面的数。
时间复杂度 。
CPP# include <bits/stdc++.h>
using namespace std;
struct arr{
long long v;
long long new_v;
int idx;
};
arr arr1[200005];
arr arr2[200005];
bool cmp1(arr a,arr b) {return a.new_v > b.new_v;}
bool cmp2(arr a,arr b) {return a.new_v < b.new_v;}
bool cmp3(arr a,arr b) {return a.idx < b.idx;}
void solve()
{
int n,m;
scanf ("%d %d",&n,&m);
for (int i=0;i<n;i++) scanf ("%lld",&arr1[i].v);
for (int i=0;i<n;i++) scanf ("%lld",&arr2[i].v);
for (int i=0;i<n;i++)
{
arr1[i].idx = i;
arr2[i].idx = i;
arr1[i].new_v=arr1[i].v%m;
arr2[i].new_v=arr2[i].v%m;
}
sort(arr1,arr1+n,cmp1);
sort(arr2,arr2+n,cmp2);
long long ans=0;
int l=0,r=n-1;
for (int i=0;i<n;i++)
{
if (arr1[i].new_v + arr2[l].new_v >= m)
{
ans += (arr1[i].new_v + arr2[r].new_v) % m;
arr2[r--].idx = arr1[i].idx;
}
else
{
ans += (arr1[i].new_v + arr2[l].new_v) % m;
arr2[l++].idx = arr1[i].idx;
}
}
sort(arr2,arr2+n,cmp3);
printf ("%lld\n",ans);
for (int i=0;i<n;i++) printf ("%lld ",arr2[i].v);
printf ("\n");
return ;
}
int main (void)
{
int T;
scanf ("%d",&T);
while (T--)
{
solve();
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...