NEC Programming Contest 2022 (AtCoder Beginner Contest 267) C D E
https://atcoder.jp/contests/abc267
C - Index × A(Continuous ver.)
不难想到前缀和,处理两个前缀和:
\(S1_i=\sum_{j=i}^{n}a_j\)
\(S2_i=\sum_{j=i}^{n}S1_j\)
那么题目中的式子就能转化为:
\(\sum_{i=l}^{l+m-1}i \cdot a_i=S2_i-S2_{i+m}-m\cdot S1_{i+m}\)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=2e5+5;
ll n,m;
ll a[N],s1[N],s2[N],ans;
int main(){
scanf("%lld%lld",&n,&m);
ans=-1e18;
for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
for(ll i=n;i;i--) s1[i]=s1[i+1]+a[i];
for(ll i=n;i;i--) s2[i]=s2[i+1]+s1[i];
for(ll i=1;i<=n-m+1;i++)
ans=max(s2[i]-s2[i+m]-m*s1[i+m],ans);
cout << ans;
return 0;
}
D - Index × A(Not Continuous ver.)
直接DP
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=2e3+5;
ll n,m;
ll a[N],f[N][N];
int main(){
scanf("%lld%lld",&n,&m);
memset(f,-0x3f,sizeof(f));
for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
for(ll i=0;i<=n;i++) f[i][0]=0;
for(ll i=1;i<=n;i++){
for(ll j=1;j<=m;j++){
f[i][j]=max(f[i-1][j],f[i-1][j-1]+j*a[i]);
}
}
cout << f[n][m];
return 0;
}
E - Erasing Vertices 2
贪心,每次拿最小的
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=2e5+5;
int n,m;
int a[N];
ll s[N];
ll ans;
bool t[N];
vector<int>e[N];
priority_queue<pair<ll,int>,vector<pair<ll,int> >,greater<pair<ll,int> > > pq;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
for(int i=1;i<=n;i++) {
for(auto j : e[i])
s[i]+=a[j];
pq.push(make_pair(s[i],i));
}
while(!pq.empty()){
ll sum=pq.top().first;
int u=pq.top().second;
pq.pop();
if(t[u]) continue;
t[u]=1;
ans=max(ans,sum);
for(auto v : e[u]){
s[v]-=a[u];
pq.push(make_pair(s[v],v));
}
}
printf("%lld",ans);
return 0;
}