所有点的错误信息均为 Two same edges appear.但我觉得自己的代码应该不会输出两条相同的边,求 hack
#include <bits/stdc++.h>
#define int long long
using namespace std;
void read(int &a)
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
a=s*w;
}
void write(int x)
{
if(x<0)
putchar('-'),x=-x;
if(x>9)
write(x/10);
putchar(x%10+'0');
return;
}
const int N=1e6+10;
int n,m,jl,ans1[N],ans2[N],t,jsq,jl1[N],jl2[N],tt;
struct node{
int w,id;
}a[N];
bool cmp(node a,node b){
return a.w<b.w;
}
int check(int x){
int jsq=0;
for(int i=2;i<n;i++){
if(i>=jl){
int l=i+1,r=n,jjl=i;
while(l<=r){
int mid=l+r>>1;
if(a[i].w*a[mid].w<=x){
jjl=mid;
l=mid+1;
}
else r=mid-1;
}
jsq+=jjl-i;
}
else{
int l=i+1,r=n-1,jjl=n;
while(l<=r){
int mid=l+r>>1;
if(a[i].w*a[mid].w<=x){
jjl=mid;
r=mid-1;
}
else l=mid+1;
}
jsq+=n-jjl;
}
}
int l=2,r=jl-1,jjl=jl;
while(l<=r){
int mid=l+r>>1;
if(a[1].w*a[mid].w<=x){
jjl=mid;
r=mid-1;
}
else l=mid+1;
}
jsq+=jl-jjl;
return (m<=jsq);
}
void print(){
printf("%lld\n",jsq);
for(int i=1;i<=t;i++){
write(ans1[i]);
putchar(' ');
write(ans2[i]);
puts("");
}
return;
}
signed main(){
read(n),read(m);
if(n==1){
cout<<0;
return 0;
}
m-=(n-1);
for(int i=1;i<=n;i++){
read(a[i].w);
a[i].id=i;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
if(a[i].w>=0){
jl=i;
break;
}
}
int l=-1e12,r=1e12,ans=1e12;
if(m!=0){
while(l<=r){
int mid=l+r>>1;
if(check(mid)){
r=mid-1;
ans=mid;
}
else l=mid+1;
}
}
for(int i=2;i<n;i++){
if(a[i].w<0){
jsq+=a[i].w*a[n].w;
}
else{
jsq+=a[1].w*a[i].w;
}
}
jsq+=a[1].w*a[n].w;
t=n-1;
ans1[1]=a[1].id,ans2[1]=a[n].id;
for(int i=2;i<n;i++){
if(a[i].w<0){
ans1[i]=a[i].id,ans2[i]=a[n].id;
}
else{
ans1[i]=a[1].id,ans2[i]=a[i].id;
}
}
m+=(n-1);
if(t==m){
print();
return 0;
}
for(int i=2;i<n;i++){
if(i>=jl){
int l=i+1,r=n,jjl=i;
while(l<=r){
int mid=l+r>>1;
if(a[i].w*a[mid].w<=ans){
jjl=mid;
l=mid+1;
}
else r=mid-1;
}
for(int j=i+1;j<=jjl;j++){
if(a[i].w*a[j].w==ans){
jl1[++tt]=a[i].id,jl2[tt]=a[j].id;
}
else{
ans1[++t]=a[i].id,ans2[t]=a[j].id;
jsq+=a[i].w*a[j].w;
}
if(t==m){
print();
return 0;
}
}
}
else{
int l=i+1,r=n-1,jjl=n;
while(l<=r){
int mid=l+r>>1;
if(a[i].w*a[mid].w<=ans){
jjl=mid;
r=mid-1;
}
else l=mid+1;
}
for(int j=jjl;j<n;j++){
if(a[i].w*a[j].w==ans){
jl1[++tt]=a[i].id,jl2[tt]=a[j].id;
}
else{
ans1[++t]=a[i].id,ans2[t]=a[j].id;
jsq+=a[i].w*a[j].w;
}
if(t==m){
print();
return 0;
}
}
}
}
l=2,r=jl;
int jjl=jl;
while(l<=r){
int mid=l+r>>1;
if(a[1].w*a[mid].w<=ans){
jjl=mid;
r=mid-1;
}
else l=mid+1;
}
for(int i=jjl;i<jl;i++){
if(a[1].w*a[i].w==ans){
jl1[++tt]=a[1].id,jl2[tt]=a[i].id;
}
else{
ans1[++t]=a[1].id,ans2[t]=a[i].id;
jsq+=a[1].w*a[i].w;
}
if(t==m){
print();
return 0;
}
}
m-=t;
jsq+=m*ans;
printf("%lld\n",jsq);
for(int i=1;i<=t;i++){
write(ans1[i]);
putchar(' ');
write(ans2[i]);
puts("");
}
for(int i=1;i<=m;i++){
write(jl1[i]);
putchar(' ');
write(jl2[i]);
puts("");
}
return 0;
}