正解:堆
解题报告:
全场除了我都切了系列$kk$
首先看$n=2$的情况.
首先暴力不说?就记录一个$sum$再分别记录$xy$两维的下标存到堆里面每次取队头并继续扩展就完事$QwQ$.
然后发现会枚举重复,就不太优秀,考虑优化$QwQ$.
于是考虑记录下这个点是扩展$x$的时候扩展来的还是扩展$y$的时候扩展来的,如果是扩展$x$的时候扩展来的就只扩展$x$了,否则就$xy$都要扩展.
这样就能保证每个状态只会被扩展一次了.
然后现在考虑$n>2$的情况.
就直接当$n=2$地做$n-1$次就完事
然后这个复杂度是$O(nmlogm)$的.
优化康考试总结$QwQ$,$over$
#include<algorithm> #include<iostream> #include<iomanip> #include<vector> #include<cstdio> #include<queue> using namespace std; #define il inline #define gc getchar() #define ri register int #define rb register bool #define rc register char #define rp(i,x,y) for(ri i=x;i<=y;++i) #define my(i,x,y) for(ri i=x;i>=y;--i) const int N=1e5+10; int n,m,as; vector<int>V[N],v; struct node{int sum,fr,nwx,nwy;}; priority_queue<node>Q; il int read() { ri x=0;rb y=1;rc ch=gc; while(ch!='-' && (ch>'9' || ch<'0'))ch=gc; if(ch=='-')y=0,ch=gc; while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc; return y?x:-x; } il bool cmp(ri gd,ri gs){return gd>gs;} il bool operator < (node gd,node gs){return gd.sum>gs.sum;} il void work(ri x,ri y) { ri szx=V[x].size(),szy=V[y].size(); while(Q.size())Q.pop();;v.clear();Q.push((node){V[x][0]+V[y][0],0,0,0}); rp(i,1,m) { node nw=Q.top();Q.pop();v.push_back(nw.sum); if(nw.nwx+1<szx)Q.push((node){nw.sum-V[x][nw.nwx]+V[x][nw.nwx+1],1,nw.nwx+1,nw.nwy}); if(nw.fr)continue; if(nw.nwy+1<szy)Q.push((node){nw.sum-V[y][nw.nwy]+V[y][nw.nwy+1],0,nw.nwx,nw.nwy+1}); } V[y]=v; } int main() { //freopen("2442.in","r",stdin);//freopen("2442.out","w",stdout); ri T=read(); while(T--) { n=read();m=read();as=0; rp(i,1,n){V[i].clear();rp(j,1,m)V[i].push_back(read());sort(V[i].begin(),V[i].end());} rp(i,2,n)work(i-1,i);rp(i,0,m-1)printf("%d ",V[n][i]);printf(" "); } return 0; }