description
洛谷
求
[max_{1le i<jle n}{sum_{s=1}^{k-1}(C_s-|D_{is}-D_{js}|)-(C_k-|D_{ik}-D_{jk}|)}
]
data range
[nle 10^5,2le kle 5
]
solution
拆绝对值。
一开始的想法是3维CDQ套线段树 5维偏序
对于前(k-1)位,直接(2^{k-1})枚举每一个数的正负情况。
对于最后一位,排序即可拆掉绝对值。
居然还被卡了空间
Code
#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cassert>
#include<ctime>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define F "a"
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define RG register
using namespace std;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-6;
const int mod=1e4;
const int N=1000010;
const dd pi=acos(-1);
const int inf=2147483647;
const ll INF=1e18+1;
const ll P=100000;
inline ll read(){
RG ll data=0,w=1;RG char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
return data*w;
}
inline void file(){
srand(time(NULL)+rand());
freopen(F".in","r",stdin);
freopen(F".out","w",stdout);
}
#define fi first
#define se second
int n,k,S,c[5],v[64],x,y,ans;
pair<int,int> pre[64],suf[64],L,R,Ans;
struct wild{int d[5],id;}w[N];
bool cmp(wild x,wild y){return x.d[k-1]<y.d[k-1];}
int main()
{
n=read();k=read();S=(1<<(k-1))-1;
for(RG int i=0;i<k;i++)c[i]=read();
for(RG int i=1;i<=n;i++){
w[i].id=i;
for(RG int j=0;j<k;j++)w[i].d[j]=c[j]*read();
}
sort(w+1,w+n+1,cmp);
for(RG int s=0;s<=S;s++)pre[s]=suf[s]=(PI){-1e9,0};
for(RG int i=1;i<=n;i++){
for(RG int s=0,f=S;s<=S;s++,f=((~s)&S)){
v[s]=0;
for(RG int j=0;j<k-1;j++)
(s&(1<<j))?v[s]+=w[i].d[j]:v[s]-=w[i].d[j];
if(ans<pre[f].fi+v[s]-w[i].d[k-1]){
ans=pre[f].fi+v[s]-w[i].d[k-1];
x=w[i].id;y=pre[f].se;
if(x>y)swap(x,y);
}
}
for(RG int s=0;s<=S;s++)
pre[s]=max(pre[s],(PI){v[s]+w[i].d[k-1],w[i].id});
}
for(RG int i=n;i;i--){
for(RG int s=0,f=S;s<=S;s++,f=((~s)&S)){
v[s]=0;
for(RG int j=0;j<k-1;j++)
(s&(1<<j))?v[s]+=w[i].d[j]:v[s]-=w[i].d[j];
if(ans<suf[f].fi+v[s]+w[i].d[k-1]){
ans=suf[f].fi+v[s]+w[i].d[k-1];
x=w[i].id;y=suf[f].se;
if(x>y)swap(x,y);
}
}
for(RG int s=0;s<=S;s++)
suf[s]=max(suf[s],(PI){v[s]-w[i].d[k-1],w[i].id});
}
printf("%d %d
%d
",x,y,ans);
return 0;
}