前言
这场cf 怎么这么难 日了
补完题 才知道 难怪是手速场
就A难 把我心态搞炸了 B和C 都还行
D的话 复杂了以点点
E没看 E好像是线段树(待补)
A.Contest Start
分析样例
num begin end 干扰人数
1······0······5······2
2······2······7······2
3······4······9······1
4······6······11······0
你会发现 这里的 2 1 0 呈一个等差数列的 格式
上面的 2 2 又是一个相等的 格式
所以我们的代码可以是
等差数列+一个平衡数列
CODE
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
const int N = 1e6+10;
ll n,x,t,ls,cnt;
void solve()
{
cin>>n>>x>>t;
cnt = n-1;
ll ans = 0;
ls = min(n,t/x);
ans+=(ls+1)*ls/2;
///1 - n 中的数 统计一下等差数列
cnt -=ls;
///然后就是要求 前面不是等差数列的数
ans+=ls*cnt;
cout<<ans<<endl;
}
int main()
{
IOS;
int t;
cin>>t;
while(t -- )
solve();
return 0;
}
B. Love Song
理解错题意了日 垃圾翻译QAQ
问题
问题是 叫你把 这个字符复制 (这个字符在字母表中出现的位置)的次数 QAQ
所以我们直接统计前缀和即可
CODE:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
typedef long long ll;
string s;
int n,q;
ll pre[N];
void solve()
{
cin>>n>>q;
cin>>s;
for(int i=1; i<=n; i++)
pre[i]+=pre[i-1]+1+s[i-1]-'a';
for(int i=1; i<=q; i++)
{
int x,y;
cin>>x>>y;
cout<<pre[y]-pre[x-1]<<endl;
}
//for(int i=1;i<=n;i++)
//cout<<pre[i]<<" ";
}
int main()
{
solve();
return 0;
}
C - Stable Groups
》日了 我心想着我怎么比赛没过 还以为贪心错了 结果是ll 少开了 就全员ll呗 QAQ
思路
将区间不符合的单独领出来
然后对这个不符合的数组排序
然后我们就处理 (能少放就放的原则) 贪心的放就行
CODE
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;
ll a[N],n,x,k;
vector<ll> v;
void sovle()
{
cin>>n>>k>>x;
for(int i=1; i<=n; i++)
cin>>a[i];
ll ans = 1;
sort(a+1,a+1+n);
for(int i=2; i<=n; i++)
{
if(a[i] - a[i-1] > x)
{
ans++;
v.push_back(a[i]-a[i-1]);
}
}
sort(v.begin(),v.end());
for(auto it:v)
{
ll res = (it-1)/x;
if(res>k) break;
else k-=res,ans--;
}
cout<<ans<<endl;
}
int main()
{
ios::sync_with_stdio(false);
sovle();
return 0;
}
D - PriceFixed
思路
贪心
按照 B 关键字 从小到大排序
然后在按照 a关键字 从小到大排序
最后双指针 贪心的购买即可
(代码里有注释)
CODE
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
pair<LL, LL> arr[100010];
int n;
int main()
{
cin >> n;
for(int i = 1; i <= n; ++i) cin >> arr[i].second >> arr[i].first;
sort(arr + 1, arr + n + 1);
LL ans = 0, con = 0;
int i = 1, j = n;
while(i <= j)
{
//第i件可以用折扣购买
if(arr[i].first <= con)
{
ans += arr[i].second;
con += arr[i].second;
i++;
}
else
{
//把第j全部买完也不够/更好够
if(arr[j].second + con <= arr[i].first)
{
ans += 2 * arr[j].second;
con += arr[j].second;
j--;
}
else
{
//购买p件就行
LL p = arr[i].first - con;
arr[j].second -= p;
ans += 2 * p;
con += p;
}
}
}
cout << ans;
return 0;
}