P1631 序列合并是(M=2)时的简化问题,回到本题,我们可以先求出前(2)序列中任取一个数相加构成的前(N)小和,把这(N)个和作为一个序列,再与第(3)个序列求新的前(N)小和,以此类推,最终得到(M)个序列任取一个数相加构成的前(N)小和。整个算法的时间复杂度为(O(MNlogN))
注意点
原序列不一定有序,需要先排序。
const int N=2010;
struct Node
{
int i,j;
int sum;
bool operator<(const Node &W) const
{
return sum > W.sum;
}
};
int a[N],b[N],c[N];
int n,m;
void solve()
{
priority_queue<Node> heap;
for(int i=0;i<n;i++) heap.push({i,0,a[i]+b[0]});
for(int i=0;i<n;i++)
{
Node t=heap.top();
heap.pop();
c[i]=t.sum;
heap.push({t.i,t.j+1,a[t.i]+b[t.j+1]});
}
for(int i=0;i<n;i++) a[i]=c[i];
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>m>>n;
for(int i=0;i<n;i++) cin>>a[i];
sort(a,a+n);
for(int i=0;i<m-1;i++)
{
for(int j=0;j<n;j++) cin>>b[j];
sort(b,b+n);
solve();
}
for(int i=0;i<n;i++) cout<<a[i]<<' ';
cout<<endl;
}
//system("pause");
return 0;
}