Educational Codeforces Round 176 (Rated for Div. 2) (AB,补C)
A
idea:(因为没注意到k只能为奇数的惨案qaq)
因为奇-奇=偶,偶-偶=偶
所以只需要判断n的奇偶然后先进行一次操作即可
#include<bits/stdc++.h>
#define N 1005
#define mod 998244353
using namespace std;
typedef long long ll;void solve()
{int n,k;cin>>n>>k;ll ans = 0;if(n&1==1){n-=k;ans++;}k--;ans += (n+k-1)/k;cout<<ans<<"\n";
}
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int T = 1;cin>>T;while(T--)solve();return 0;
}
B:
注意到当k>=2的时候,任何情况下都能选前k+1个最大的(手上操作一下即可)
所以只需要特判k==1的情况(要不是被A卡了半年,一把就绿了,唉唉,这B能评1400有点虚高了)
#include<bits/stdc++.h>
#define N 1005
#define mod 998244353
using namespace std;
#define int long long
typedef long long ll;void solve()
{int n,k;cin>>n>>k;ll ans = 0;vector<int>a(n+1);for(int i = 1;i <= n;i++) {cin>>a[i];}if(k==1){for(int i = 2;i < n;i++){ans = max(ans,a[i]+max(a[1],a[n]));}ans = max(ans,a[1]+a[n]);}else{ans = 0;sort(a.begin()+1,a.end(),greater<int>());for(int i = 1;i <= k+1;i++){ans+=a[i];}}cout<<ans<<"\n";
}
signed main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int T = 1;cin>>T;while(T--)solve();return 0;
}
C:先补一下前缀预处理的写法
idea1:假设现在两种颜色,第一种选i,则第二种选n-i个,那么对每一种都这么考虑必定tle,
现在进行这样一种操作,将每个>=a[i]的用数组Num存储进行后缀和,表示现在有多少数量大于等于i的木板,当选a[i]块木板满足时,那么少选这块木板也能满足条件,e.g:对第三个样例
12 3
5 9 8
当选 i = 4;n - i = 8的时候,如果不选a[1],那么因为≥8的有8和9,所以选2:3也可以,只要a[n-i]>0
再进一步考虑,将区间划分为[i,n-i+1]和[n-i,n](因为(3,9)和(9,3)是两种选法),但只需要考虑[i,n-i-1]即可,最终将ans*2就可以解决重复计算的问题。
那么如何计算?
对于这一组样例,如果选4:8个,那么能选4的为c(1,3),能选8的为c(1,2);
假设第一种选x个,那么x = num[i] - num[n-i];(表示有多少个木板数量>=i的)
第二种则设为y = num[n-i],最终答案为ans += x×y + y×(y-1),//后面的是表示从>=i的木板中任选两块
如果i == n-i时,会出现重复,ans += x×y + y×(y-1)/2;
#include<bits/stdc++.h>
#define mod 998244353
using namespace std;
typedef long long ll;
#define int unsigned long long
int num[200005];
int N = 0;
void solve()
{int n,m;cin>>n>>m;int h = max(n,m);//T范围较大,防爆for(int i = 1;i <= h;i++) num[i] = 0;//别用memsetvector<int>a(m+1);for(int i = 1;i <= m;i++){cin>>a[i];num[a[i]]++;} for(int i = n-1;i >= 1;i--){num[i] += num[i+1];//预处理后缀和}int ans = 0;//1 : n-i 选i个,另一个选n-i个, ans += x*y+y*(y-1);//i==n-i /2for(int i = 1;i <= n-i; i++){int x = num[i] - num[n-i],y = num[n-i];if(i != n - i) ans += x*y + y*(y-1);else ans += x*y + y*(y-1)/2;}cout<<ans*2<<"\n";}
signed main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);int T = 1;cin>>T;while(T--)solve();return 0;
}