CF2003F 解题报告
题目描述
现在有三个长度为
。 。 是互不相同的。
在此基础上最大化
思路点拨
看了一眼这个题目的官解,十分牛逼。但是这里要给一个正确性
考虑对于每一个
直接枚举
直接枚举二元组就可以。时间复杂度
考虑枚举
我们记录
接下来在枚举
时间复杂度
考虑枚举
我们沿用
再定义
接下来在枚举
首先沿用
这个时候我们枚举
实际上,想要求出
这样子可以通过
表面上,这个时间复杂度是光鲜的
这个时间复杂度想要通过是十分极限的,所以我推荐你添加如下两种优化:
-
精细化实现,例如在枚举
的过程中,一旦发现有 相同立马跳出循环。 -
线段树改写树状数组,因为是前缀问题。
#include<bits/stdc++.h>
//#define int long long
using namespace std;
namespace fastIO{
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-f;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int buf[20],TOT;
inline void print(int x,char ch=' '){
if(x<0) putchar('-'),x=-x;
else if(x==0) buf[++TOT]=0;
for(int i=x;i;i/=10) buf[++TOT]=i%10;
do{putchar(buf[TOT]+'0');}while(--TOT);
putchar(ch);
}
}
using namespace fastIO;
const int MAXN=3e3+5,inf=1e9;
int n,m,a[MAXN],b[MAXN],c[MAXN];
int ans=-1;
struct node{
int pos[6],val[6];
node(){
for(int i=1;i<=5;i++)
pos[i]=0,val[i]=-inf;
}
void insert(int p,int v){
for(int i=1;i<=5;i++){
if(v>val[i]){
int flag=5;
for(int j=i;j<=5;j++)
if(pos[j]==p) flag=j;
for(int j=flag;j>i;j--)
pos[j]=pos[j-1],val[j]=val[j-1];
pos[i]=p,val[i]=v;
break;
}
else if(p==pos[i])
break;
}
}
node friend operator+(const node &a,const node &b){
node c;
for(int i=1;i<=5;i++)
c.insert(a.pos[i],a.val[i]);
for(int i=1;i<=5;i++)
c.insert(b.pos[i],b.val[i]);
return c;
}
};
node pre[MAXN],suf[MAXN],t[MAXN];
#define lowbit(x) (x&(-x))
void update(int x,pair<int,int> w){
for(int i=x;i<=n;i+=lowbit(i))
t[i].insert(w.first,w.second);
}
node query(int x){
node ans;
for(int i=x;i;i-=lowbit(i))
ans=ans+t[i];
return ans;
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) b[i]=read();
for(int i=1;i<=n;i++) c[i]=read();
if(m==1){
for(int i=1;i<=n;i++)
ans=max(ans,c[i]);
cout<<ans;
}
else if(m==2){
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(a[i]<=a[j]&&b[i]!=b[j])
ans=max(ans,c[i]+c[j]);
cout<<ans;
}
else if(m==3){
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(a[i]<=a[j]) suf[i].insert(b[j],c[j]);
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(a[i]<=a[j]&&b[i]!=b[j]){
for(int k=1;k<=5;k++){
if(b[i]==suf[j].pos[k]||b[j]==suf[j].pos[k])
continue;
ans=max(ans,c[i]+c[j]+suf[j].val[k]);
}
}
}
}
cout<<ans;
}
else if(m==4){
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(a[i]<=a[j]) suf[i].insert(b[j],c[j]);
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
if(a[j]<=a[i]) pre[i].insert(b[j],c[j]);
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(a[i]<=a[j]&&b[i]!=b[j]){
for(int p=1;p<=5;p++){
if(pre[i].pos[p]==b[i]||pre[i].pos[p]==b[j]) continue;
for(int q=1;q<=5;q++){
if(pre[i].pos[p]!=suf[j].pos[q]&&suf[j].pos[q]!=b[i]&&suf[j].pos[q]!=b[j])
ans=max(ans,c[i]+c[j]+pre[i].val[p]+suf[j].val[q]);
}
}
}
}
}
cout<<ans;
}
else if(m==5){
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(a[i]<=a[j]) suf[i].insert(b[j],c[j]);
for(int i=1;i<=n;i++)
for(int j=1;j<i;j++)
if(a[j]<=a[i]) pre[i].insert(b[j],c[j]);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++) t[j]=node();
for(int j=i+2;j<=n;j++){
if(a[i]<=a[j-1])
update(a[j-1],make_pair(b[j-1],c[j-1]));
if(a[i]<=a[j]&&b[i]!=b[j]){
node tmp=query(a[j]);
for(int x=1;x<=5;x++){
int p1=pre[i].pos[x];
if(!p1) continue;
if(p1==b[i]||p1==b[j]) continue;
for(int y=1;y<=5;y++){
int p2=tmp.pos[y];
if(!p2) continue;
if(p2==p1||p2==b[i]||p2==b[j]) continue;
for(int z=1;z<=5;z++){
int p3=suf[j].pos[z];
if(!p3) continue;
if(p3==p1||p3==p2||p3==b[i]||p3==b[j]) continue;
ans=max(ans,c[i]+c[j]+pre[i].val[x]+tmp.val[y]+suf[j].val[z]);
break;
}
}
}
}
}
}
cout<<ans;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?