CF2185 比赛题解
A
#include<iostream>
using namespace std;
int main(){
int t,n;
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++){
cout<<i<<" ";
}
cout<<endl;
}
return 0;
}
B
#include<iostream>
using namespace std;
int t,n,a[55];
int f(){
int mx=0,ans=0;
for(int i=1;i<=n;i++){
mx=max(mx,a[i]);
ans+=mx;
}
return ans;
}
int main(){
cin>>t;
while(t--){
int ret=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
ret=f();
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
swap(a[i],a[j]);
ret=max(ret,f());
swap(a[i],a[j]);
}
}
cout<<ret<<endl;
}
return 0;
}
C
\(*\color{gray}{106}\)
考虑 \(\operatorname{mex}\) 的最小值是 \(0\) ,如果它最后不是 \(0\) ,那么一定存在一个 \(i\) 满足 \(a_i+x=0\) ,这个时候可以发现一个性质:
- Observation 1 :令 \(h_i=[是否存在j使得a_j=i]\) ,那么答案为 \(h\) 的连续极大全为
1段长度。
接下来我们用离散化随便处理一下即可。
#include<iostream>
using namespace std;
int t,n,a[3005],qn,f[3005],ans;
int main(){
cin>>t;
while(t--){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1);
qn=unique(a+1,a+n+1)-a-1;
ans=0;
for(int i=1;i<=qn;i++){
f[i]=1;
if(a[i]==a[i-1]+1&&i>=2){
f[i]=f[i-1]+1;
}
ans=max(ans,f[i]);
}
cout<<ans<<endl;
}
return 0;
}
D
\(*\color{brown}{469}\)
首先注意到 \(a\) 在不重置的状态下是单调不降的,因此可以随着修改 \(O(1)\) 更新全局最大值。
然后当我们需要重置的时候,可以用一个 vector 存下来在上次重置之后有所修改的元素情况,只对这部分的元素进行修改即可,可以证明复杂度是 \(O(n)\) 的。
#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
ll t,n,m,h,a[200005],A[200005],b,c,mx,qmx;
vector<ll> vc;
int main(){
cin>>t;
while(t--){
cin>>n>>m>>h;
qmx=mx=0;
for(ll i=1;i<=n;i++){
cin>>a[i];
A[i]=a[i];
qmx=max(qmx,a[i]);
}
mx=qmx;
for(ll i=1;i<=m;i++){
cin>>b>>c;
a[b]+=c;
mx=max(mx,a[b]);
vc.push_back(b);
if(mx>h){
mx=qmx;
for(ll j=0;j<vc.size();j++){
ll ids=vc[j];
a[ids]=A[ids];
}
vc.clear();
}
}
for(ll i=1;i<=n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}
return 0;
}

浙公网安备 33010602011771号