[WC2005]友好的生物

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;
}

原文地址:https://www.cnblogs.com/cjfdf/p/9807294.html