ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

[题解]BYOI Round 1 T1~T2

2026/8/8 3:46:14 拓冰建站 浏览量
[题解]BYOI Round 1 T1~T2

比赛页面

VP.

T1. P14524 意识解离

每出现一个 \(a[i-1]<a[i]\)(特别地,令 \(a[0]=-\infty\)),说明必须新增一个长度为 \(n-i+1\) 的序列。

因此,有解的充要条件是 \(\forall i\in[1,n],a[i]\ge \sum_{j=1}^i \big[a[j]>a[j-1]\big]\)

时间复杂度 \(O(n)\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5;
int t,n,a[N];
inline bool solve(){for(int i=1,c=0;i<=n;i++){if(a[i]>a[i-1]) c++;if(a[i]<c) return 0;}return 1;
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>t;a[0]=-2e9;while(t--){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];cout<<(solve()?"Yes\n":"No\n");}return 0;
}

T2. P14525 幻想碎片

看到数据范围和时限(500ms),复杂度大概是 \(O(n^3)\) 的。

我们枚举左右边缘 \(l,r\),中间部分看做一个长度为 \(n\) 的序列。

对于行数 \(\ge\) 列数,只需求出该序列长度 \(\ge (r-l+1)\) 的最大子段和,再乘上列数 \((r-l+1)\) 即可计入贡献。

对于行数 \(\le\) 列数,我们发现不好统计。但是将矩阵转置一下,就转化为行数 \(\ge\) 列数了!

时间复杂度 \(O(n^3)\)

点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=405,inf=1e15;
inline void chmx(int &x,int y){x=max(x,y);}
int n,m,a[N][N],s[N][N],t[N],ans=-inf;
inline void solve(){for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) s[i][j]=s[i][j-1]+a[i][j];for(int i=1;i<=m;i++){for(int j=i;j<=m;j++){if(j-i+1>n) continue;for(int k=1;k<=n;k++) t[k]=t[k-1]+s[k][j]-s[k][i-1];int l=j-i+1,s=t[l],mx=t[l];for(int k=l+1;k<=n;k++) s=max(t[k]-t[k-l],s+t[k]-t[k-1]),mx=max(mx,s);//len>=l的最大子段和ans=max(ans,mx*l);}}
}
inline void tran(){for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) s[j][i]=a[i][j];swap(n,m);for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=s[i][j]; 
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>a[i][j];}}solve(),tran(),solve();cout<<ans<<"\n";return 0;
}