CF补题 993-Div.4

CF补题 993-Div.4-20241221

Dashboard - Codeforces Round 993 (Div. 4) - Codeforces

A:

题目大意:给出一个 \(n\) ,求有多少有序正整数数对 \((a,b)\),使得 \(a=n-b\)

#include <iostream>
#define streampreset() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
int main()
{
streampreset();
int T;
cin >> T;
while (T--)
{
int n;
cin >> n;
cout << n - 1 << endl;
}
return 0;
}

经典数学小知识

B:

题目大意:给出一个由 p,q,w 组成的字符串,求它的镜像串

#include <iostream>
#include <string>
#define streampreset() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
int main()
{
streampreset();
int T;
cin >> T;
while (T--)
{
string a;
cin >> a;
for (int i = a.size() - 1; i >= 0; i--) {
if (a[i] == 'q') cout << 'p';
else if (a[i] == 'p') cout << 'q';
else cout << a[i];
}
cout << endl;
}
return 0;
}

正序输入,倒序输出,p,q 翻转 w 不变

C:

题目大意:\(2*m\) 个座位有 \(a+b+c\) 只猴子,\(a\) 猴子只能坐第一排, \(b\) 猴子只能坐第二排,\(c\) 猴子随便坐,求最大能坐下的猴子数

#include <iostream>
#include <algorithm>
#define streampreset() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
int main()
{
streampreset();
int T;
cin >> T;
while (T--)
{
int m, a, b, c;
int ans = 0;
cin >> m >> a >> b >> c;
ans+=min(a,m);
ans+=min(b,m);
ans+=min(2*m-min(a,m)-min(b,m),c);
cout<<ans<<endl;
}
return 0;
}

贪心,首先安排 \(a,b\) 猴子,剩下的座位就是 \(c\) 猴的

D:

题目大意:给出一个序列a,构造一个序列b使得 \(a_i\)\(1\le i \le n\) 上的 \([b_1,b_2...b_i]\) 的模,模指的是一个序列中出现次数最多的数(众数)

#include <iostream>
#define streampreset() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
int a, st[200010];
int n;
int main()
{
streampreset();
int T;
cin >> T;
while (T--)
{
memset(st, 0, sizeof st);
cin >> n;
int d = 1;
for (int i = 1; i <= n; i++) {
cin >> a;
while (st[d]) d++;//定位
if (st[a]) {
cout << d << ' ';//如果出现过,就填d
st[d]++;
}
else {
cout << a << ' ';没有出现过,就填a
st[a]++;
}
}
cout << endl;
}
return 0;
}

脑筋急转弯,只要我们保证每次出现的数都不重复,即每个数都只出现一次,那么所有的数都是这个序列的模

所以我们维护一个状态序列,每次判断当前的 \(a_i\) 是否出现过,如果出现过,就使 \(b_i\) 为一个从未出现过的数,如果没有出现过,我们就把他加入序列

每次循环前,都要将d定位到没有出现过的数上

E:

题目大意:对 \(x,y\) 两个正整数,给定两个区间 l1,r1,l2,r2 和一个底数 k ,求满足 \(\frac{y}{x}=k^n\)\((x,y)\) 有序对数

#include <iostream>
#include <algorithm>
#include <math.h>
#define streampreset() ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
int main()
{
streampreset();
int T;
cin >> T;
while (T--)
{
long long k, la, ra, lb, rb;
cin >> k >> la >> ra >> lb >> rb;
long long sum = 1;
long long ans = 0;
long long u, v;
while (sum <= rb) {
long long i = la - 1, j = ra + 1;
while (i + 1 != j)
{
long long mid = (i + j) >> 1;
if (mid * sum >= lb) j = mid;//
else i = mid;
}
u = j;//取分界右侧
i = la - 1, j = ra + 1;
while (i + 1 != j)
{
long long mid = (i + j) >> 1;
if (mid *sum > rb) j = mid;
else i = mid;
}
v = i;//取分界左侧
if (u <= v) ans += v - u + 1;
sum *= k;
}
cout << ans << endl;
}
return 0;
}

\(\frac{y}{x}=k^n\) 可变形为 \(y=x*k^n\)\(x=\frac{y}{k^n}\) ,我们已知 \(x,y\) 的取值范围,通过枚举 \(n\) 再二分查找 \(x\) 的边界

枚举 \(n\) 只需要枚举到 \(k^n\le y_{max}\) ,因为超过界限后,左右边界都为 \(0\) 无意义

二分找 \(x\) 的边界,分别求满足 \(x*k^n=y_{min}\)\(x*k^n=y_{max}\)\(x_u,x_v\)

最后答案加上 \(\sum_{u}^{v}(x)\) 即可,复杂度大约在 \(O(n\log n)\) 左右

posted @   才瓯  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示