Atcoder ABC 309 F
Atcoder ABC 309 F
题意
n个盒子,长宽高为(长宽高是相对的,可以任意调换),问是否有一个盒子可以完全容纳另一个盒子,即存在一个 ,使得
思路
思考一个简单的问题:对于二元组,我们怎么确定存在两个二元组,答案自然是树状数组,以第一关键字为下标,用树状数组维护第一关键字在的最小的值.
这题就是多了一个关键字而已,以多出的一个关键字排序,之后放在外层枚举,注意外层关键字不能相同。
代码
struct node
{
int a,b,c;
//因为可以任意调换,就按从小到大排序
void init()
{
if(a>b) swap(a,b);
if(b>c) swap(b,c);
if(a>b) swap(a,b);
}
}d[N];
bool cmp(node a,node b)
{
return a.a<b.a;
}
int p[N],f[N*3];
int get(int x)
{
int ans=inf;
while(x) ans=min(ans,f[x]),x-=(x&-x);
return ans;
}
void modify(int x,int y)
{
while(x<=n) f[x]=min(f[x],y),x+=(x&-x);
}
void solve()
{
cin>>n;
for(int i=0;i<=n*2;i++) f[i]=inf;//树状数组维护最小值,要
for(int i=1;i<=n;i++) cin>>d[i].a>>d[i].b>>d[i].c,d[i].init();
sort(d+1,d+1+n,cmp);//以第一关键字排序
//第二关键字 离散化
for(int i=1;i<=n;i++) p[i]=d[i].b;
sort(p+1,p+1+n);
for(int i=1;i<=n;i++)
{
d[i].b = lower_bound(p+1,p+1+n,d[i].b)-p;
}
for(int i=1;i<=n;i++)
{
if(d[i].a!=d[i+1].a)
{
//已经保证第一关键字一定大于前面的,当前的还未加入树状数组
for(int j=i;j>=1;j--)
{
if(d[j].a!=d[i].a) break;
if(get(d[j].b-1)<d[j].c)
{
cout<<"Yes\n";
return;
}
}
for(int j=i;j>=1;j--)
{
if(d[j].a!=d[i].a) break;
modify(d[j].b,d[j].c);
}
}
}
cout<<"No\n";
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)