# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1178637 | 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,k,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 G;
void gcd2(__int128 x,__int128 y){
if(x<y)swap(x,y);
while(y){
x%=y;
swap(x,y);
}
G=x;
}
struct fraction{
// A / B
__int128 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({(int)choose.f.A,(int)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<<" ";
}
/*
*/