题解:球状精灵的传说
我们记三个维度为最大值,中间值和最小值。容易发现只需要将三个值排序,检查最大值和中间值相同,融合最小值的情况。
题意中的融合操作只会造成两种影响,一个是融合之后新最小值依然比中间值小,这并不会对答案产生贡献;还有就是融合后的新最小值超过了中间值,所以中间值成为了新的最小值,会产生新的结果。
既然我们要尽量让两个可以融合的精灵的最小值相加尽可能大,就可以维护一个大根堆,取出前两个元素来判断是否合法。使用 \(map\) 维护,以另外两个维度为关键字。由于还要维护最大值从哪里得来,所以优先队列要维护 \(pair\),以值为第一关键字,位置为第二关键字。答案遍历 \(map\) 统计即可。
复杂度 \(O(n \log^2 n)\),再次喜提最劣解。
\(Code\)
#include<bits/stdc++.h>
#define MAX 1000010
#define int long long
using namespace std;
inline int read()
{
int s=0,w=1;
char c=getchar();
while(!isdigit(c)) {if(c=='-') w=-1; c=getchar();}
while(isdigit(c)) s=(s<<1)+(s<<3)+(c^48),c=getchar();
return s*w;
}
int n;
struct rest
{
int a,b,c;
#define a(i) r[(i)].a
#define b(i) r[(i)].b
#define c(i) r[(i)].c
void fix(){int t=a+b+c,tt=a; a=max(max(a,b),c),c=min(min(tt,b),c),b=t-a-c;}
}r[MAX];
map<pair<int,int>,priority_queue<pair<int,int> > > q;
int maxx;
pair<int,int> ans;
signed main()
{
n=read();
for(int i=1;i<=n;++i)
{
a(i)=read(),b(i)=read(),c(i)=read();
r[i].fix();
int now=c(i)*c(i)*c(i)/4;
if(now>maxx) maxx=now,ans.first=i,ans.second=i;
q[make_pair(a(i),b(i))].push(make_pair(c(i),i));
}
map<pair<int,int>,priority_queue<pair<int,int> > >::reverse_iterator iter;
for(iter=q.rbegin();iter!=q.rend();++iter)
{
if(iter->second.size()<2) continue;
pair<int,int> x=iter->second.top();
iter->second.pop();
pair<int,int> y=iter->second.top();
int bb=iter->first.second;
if(x.first+y.first>=bb)
{
int now=bb*bb*bb/4;
if(now>maxx) maxx=now,ans.first=x.second,ans.second=y.second;
}
}
if(ans.first==ans.second) cout<<0<<endl<<ans.first<<endl<<maxx;
else cout<<1<<endl<<ans.first<<" "<<ans.second<<endl<<maxx;
return (0-0);
}