| # | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 | 
|---|---|---|---|---|---|---|---|
| 1178642 | 8pete8 | Naan (JOI19_naan) | C++20 | 0 ms | 0 KiB | 
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define f first
#define s second
#define pii pair<int,int>
#define ppii pair<int,pii>
#define vi vector<int>
#define pb push_back
#define all(x) x.begin(),x.end()
#define rall(x) x.rbegin(),x.rend()
#define F(n) for(int i=0;i<n;i++)
#define lb lower_bound
#define ub upper_bound
#define fastio ios::sync_with_stdio(false);cin.tie(NULL);
#pragma GCC optimize ("03,unroll-lopps")
#define sz(x) (int)((x).size())
#define int long long
using namespace std;
const int mod=1e9+7,mxn=2e3+10,inf=1e18,minf=-1e18,lg=20,Mxn=1e9;
//#undef int
int n,m,d,q;
void setIO(string name){
	ios_base::sync_with_stdio(0); cin.tie(0);
	freopen((name+".in").c_str(),"r",stdin);
	freopen((name+".out").c_str(),"w",stdout);
}
__int128_t G;
void gcd2(__int128_t x,__int128_t y){
	if(x<y)swap(x,y);
	while(y){
		x%=y;
		swap(x,y);
	}
	G=x;
}
struct fraction{
	// A / B
	__int128_t A=0,B=1;
	void reduce(){
		gcd2(A,B);
		if(G){
			A/=G;
			B/=G;
		}
	}
	void operator-=(fraction &o){
		if(o.B==B)A-=o.A;
		else{
			A*=o.B;
			A-=(o.A*B);
			B*=o.B;
		}
		reduce();
	}
	void operator+=(fraction &o){
		if(o.B==B)A+=o.A;
		else{
			A*=o.B;
			A+=(o.A*B);
			B*=o.B;
		}
		reduce();
	}
	fraction operator+(fraction &o){
		fraction x;
		x.A=A,x.B=B;
		x+=o;
		return x;
	}
	fraction operator-(fraction &o){
		fraction x;
		x.A=A,x.B=B;
		x-=o;
		return x;
	}
	fraction operator/(fraction &o){
		fraction x;
		x.A=A*o.B,x.B=B*o.A;
		x.reduce();
		return x;
	}
	fraction operator*(fraction &o){
		fraction x;
		x.A=A*o.A,x.B=B*o.B;
		x.reduce();
		return x;
	}
	int cmp(fraction &y)const{
		if((__int128_t)(A*y.B)<(__int128_t)(y.A*B))return -1;
		else if((__int128_t)(A*y.B)>(__int128_t)(y.A*B))return 1;
		return 0;
	}
	bool operator<=(fraction &o)const{return cmp(o)<=0;}
	bool operator<(fraction &o)const{return cmp(o)<0;}
	bool operator==(fraction &o)const{return cmp(o)==0;}
	bool operator>=(fraction &o)const{return cmp(o)>=0;}
};
fraction v[mxn+10][mxn+10];
fraction need[mxn+10];
fraction go[mxn+10][mxn+10];
int P[mxn+10];
int dead[mxn+10];
int32_t main(){
	fastio
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			int x;cin>>x;
			v[i][j].A=x;
			need[i].A+=v[i][j].A;
		}
		P[i]=1;
		need[i].B=n;
	}
	vector<int>ord;
	for(int i=1;i<=n;i++){
		int cur=1;
		fraction bound=need[i],sum;
		for(int j=1;j<n;j++){
			while(cur<=m&&sum+v[i][cur]<=bound){
				sum+=v[i][cur];
				cur++;
			}
			fraction x=bound-sum;
			x=(x/v[i][cur]);
			bound+=need[i];
			go[i][j]={(cur-1)*x.B+x.A,x.B};
		}
	}
	vector<pii>ans;
	for(int k=1;k<n;k++){
		pair<fraction,int>choose;
		choose.s=inf;
		for(int i=1;i<=n;i++)if(!dead[i]){
			if(choose.s==inf||go[i][k]<=choose.f)choose={go[i][k],i};
		}
		ans.pb({choose.f.A,choose.f.B});
		ord.pb(choose.s);
		dead[choose.s]=1;
	}
	for(auto i:ans)cout<<i.f<<' '<<i.s<<'\n';
	for(int i=1;i<=n;i++)if(!dead[i])ord.pb(i);
	for(auto i:ord)cout<<i<<" ";
}
/*
*/
