题目地址
本期难度适中
C - One More aab aba baa
简单题,stl中next_permutation会用就行
/*
* @Author: C.D.
* @Date: 2024-02-23 11:20:19
* @LastEditors: C.D.
* @LastEditTime: 2024-03-05 16:47:57
* @FilePath: \atcoder\atcoder.cpp
*
* Copyright (c) 2024 by C.D./tongwoo.cn, All Rights Reserved.
*/
#include <iostream>
#include <string>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <unordered_map>
#include <algorithm>
#define LT(x) (x * 2)
#define RT(x) (x * 2 + 1)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
int main()
{
//freopen("in.txt", "r", stdin);
string s;
int n;
cin >> s >> n;
sort(s.begin(), s.end());
// cout << s << endl;
set<string> ss;
do {
ss.insert(s);
} while(next_permutation(s.begin(), s.end()));
vector<string> vs;
for (auto str: ss) vs.push_back(str);
sort(vs.begin(), vs.end());
cout << vs[n - 1] << endl;
return 0;
}
D - Coprime 2
简单数论题,对a数组分解质因数,再枚举k
/*
* @Author: C.D.
* @Date: 2024-02-23 11:20:19
* @LastEditors: C.D.
* @LastEditTime: 2024-03-05 16:55:02
* @FilePath: \atcoder\atcoder.cpp
*
* Copyright (c) 2024 by C.D./tongwoo.cn, All Rights Reserved.
*/
#include <iostream>
#include <string>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <unordered_map>
#include <algorithm>
#define LT(x) (x * 2)
#define RT(x) (x * 2 + 1)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
int n, m;
bool vis[100020];
set<int> p;
void insert(int x) {
for (int i = 2; i * i <= x; ++ i) {
while(x % i == 0) {
p.insert(i);
x /= i;
}
}
if(x != 1) {
p.insert(x);
}
}
int main()
{
//freopen("in.txt", "r", stdin);
scanf("%d%d", &n, &m);
for(int i = 0; i < n; ++ i) {
int t;
scanf("%d", &t);
insert(t);
}
for (auto x: p) {
for (int i = 1; i * x <= m; ++ i) {
vis[i * x] = 1;
}
}
int cnt = 0;
for (int i = 1; i <= m; ++ i) {
if(!vis[i]) cnt ++;
}
printf("%d\n", cnt);
for(int i = 1; i <= m; ++ i) {
if(!vis[i]) printf("%d\n", i);
}
return 0;
}
E - Chain Contestant
二维的dp方程看不懂,写个三维的
A-J映射到0-9
f
(
i
,
m
a
s
k
,
j
)
f(i,mask,j)
f(i,mask,j)代表当前搜到的位置为i,前面i位组成的bitmask为mask,最后一个参加的比赛为j
不选:
f
(
i
,
m
a
s
k
,
j
)
+
=
f
(
i
−
1
,
m
a
s
k
,
j
)
f(i,mask,j)+=f(i-1,mask,j)
f(i,mask,j)+=f(i−1,mask,j)
选并且前一个是j
f
(
i
,
m
a
s
k
,
j
)
+
=
f
(
i
−
1
,
m
a
s
k
,
j
)
f(i,mask,j)+=f(i-1,mask,j)
f(i,mask,j)+=f(i−1,mask,j)
选并且前一个不是j
f
(
i
,
m
a
s
k
,
j
)
+
=
∑
f
(
i
−
1
,
p
r
e
,
k
)
f(i,mask,j)+= \sum f(i-1, pre,k)
f(i,mask,j)+=∑f(i−1,pre,k)
其中
p
r
e
pre
pre是去掉当前的j后的位编码.
/*
* @Author: C.D.
* @Date: 2024-02-23 11:20:19
* @LastEditors: C.D.
* @LastEditTime: 2024-03-07 09:29:57
* @FilePath: \atcoder\atcoder.cpp
*
* Copyright (c) 2024 by C.D./tongwoo.cn, All Rights Reserved.
*/
#include <iostream>
#include <string>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <unordered_map>
#include <algorithm>
#define LT(x) (x * 2)
#define RT(x) (x * 2 + 1)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
ll mod = 998244353;
ll f[1002][1024][10];
int a[1002];
int n;
void inline add_mod(ll &x, ll add){
x = (x + add) % mod;
}
int main()
{
//freopen("in.txt", "r", stdin);
scanf("%d", &n);
char s[1001];
scanf("%s", s);
for(int i = 0; i < n; ++ i) {
a[i + 1] = s[i] - 'A';
}
for (int i = 1; i <= n; ++ i) {
for(int j = 0; j < 1024; ++ j) {
for (int k = 0; k < 10; ++ k) {
if(((j >> k) & 1) == 0) continue;
if(a[i] != k) {
add_mod(f[i][j][k], f[i - 1][j][k]);
} else {
int pre = j ^ (1 << k);
add_mod(f[i][j][k], f[i - 1][j][k] * 2);
if(pre == 0) {
add_mod(f[i][j][k], 1);
} else {
for(int l = 0; l < 10; ++ l){
if(l != k) add_mod(f[i][j][k], f[i - 1][pre][l]);
}
}
}
}
}
}
ll ans = 0;
for(int i = 1; i < 1024; ++ i) {
for(int j = 0; j < 10; ++ j) {
add_mod(ans, f[n][i][j]);
}
}
printf("%lld\n", ans);
return 0;
}
F - Dist Max 2
最小值求最大值,二分
这里求
G
=
min
(
∣
x
i
−
x
j
∣
,
∣
y
i
−
y
j
∣
)
G=\min(\lvert x_i-x_j \rvert, \lvert y_i-y_j \rvert)
G=min(∣xi−xj∣,∣yi−yj∣)的最大值,
也就是求
G
≥
g
G \ge g
G≥g成立下
max
g
\max g
maxg
即判断
∀
i
,
j
\forall i,j
∀i,j,
∣
x
i
−
x
j
∣
≥
g
\lvert x_i-x_j \rvert \ge g
∣xi−xj∣≥g且
∣
y
i
−
y
j
∣
≥
g
\lvert y_i-y_j \rvert \ge g
∣yi−yj∣≥g是否成立
这里可以对x排序然后采用滑动窗口的方法
/*
* @Author: C.D.
* @Date: 2024-02-23 11:20:19
* @LastEditors: C.D.
* @LastEditTime: 2024-03-07 14:12:54
* @FilePath: \atcoder\atcoder.cpp
*
* Copyright (c) 2024 by C.D./tongwoo.cn, All Rights Reserved.
*/
#include <iostream>
#include <string>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <unordered_map>
#include <algorithm>
#define LT(x) (x * 2)
#define RT(x) (x * 2 + 1)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
struct Node{
int x, y;
};
Node a[200020];
int lmin[200020], lmax[200020];
int rmin[200020], rmax[200020];
int n;
bool check(ll val){
int i = 0, j = -1;
while(i < n && j < n) {
while(j + 1 < n && abs(a[i].x - a[j + 1].x) < val){
j += 1;
}
//printf("%d %d\n", i, j);
if(j + 1 < n) {
if(abs(lmax[i] - rmin[j + 1]) >= val) return true;
if(abs(lmin[i] - rmax[j + 1]) >= val) return true;
}
i += 1;
}
return false;
}
int main()
{
//freopen("in.txt", "r", stdin);
scanf("%d", &n);
for(int i = 0; i < n; ++ i) {
int x, y;
scanf("%d%d", &x, &y);
a[i] = Node({x, y});
}
sort(a, a + n, [&](Node lhs, Node rhs) {
return lhs.x < rhs.x;
});
lmin[0] = lmax[0] = a[0].y;
for(int i = 1; i < n; ++ i) {
lmin[i] = min(lmin[i - 1], a[i].y);
lmax[i] = max(lmax[i - 1], a[i].y);
}
rmin[n - 1] = rmax[n - 1] = a[n - 1].y;
for(int i = n - 2; i >= 0; -- i) {
rmin[i] = min(rmin[i + 1], a[i].y);
rmax[i] = max(rmax[i + 1], a[i].y);
}
//check(1);
ll lo = 0, hi = 1e10;
while(lo < hi) {
ll mi = (lo + hi) / 2;
bool ret = check(mi);
if(ret) lo = mi + 1;
else hi = mi;
}
printf("%lld\n", lo - 1);
return 0;
}
G - Colorful Candies 2
每个球取是独立事件,因此求取颜色期望数,可以单独计算n个球里面取k个,取到每个颜色的期望,再加起来
E
(
k
)
=
∑
(
C
n
k
−
C
n
−
c
i
k
C
n
k
)
E(k)=\sum(\frac{C_n^k-C_{n-ci}^k}{C_n^k})
E(k)=∑(CnkCnk−Cn−cik)
其中ci是每个颜色的数量
但是颜色也很多,整个算法
O
(
N
2
)
O(N^2)
O(N2)
可以发现 相同数量的可以合并,于是算法复杂度就降下来了
/*
* @Author: C.D.
* @Date: 2024-02-23 11:20:19
* @LastEditors: C.D.
* @LastEditTime: 2024-03-08 10:25:16
* @FilePath: \atcoder\atcoder.cpp
*
* Copyright (c) 2024 by C.D./tongwoo.cn, All Rights Reserved.
*/
#include <iostream>
#include <string>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <unordered_map>
#include <algorithm>
#define LT(x) (x * 2)
#define RT(x) (x * 2 + 1)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
int n;
map<int, int> a; // [颜色数量ci,颜色数量为ci的有几个]
int m;
map<int, int> cnt;
ll mod = 998244353;
ll fac[50005], inv[50005];
ll qpow(ll a, ll x) {
if(x == 0) return 1ll;
ll t = qpow(a, x >> 1);
if(x & 1) return t * t % mod * a % mod;
else return t * t % mod;
}
void init() {
fac[0] = fac[1] = 1;
for(int i = 2; i <= n; ++ i) {
fac[i] = fac[i - 1] * i % mod;
}
inv[n] = qpow(fac[n], mod - 2);
for (int i = n - 1; i >= 0; -- i) {
inv[i] = inv[i + 1] * (i + 1) % mod;
}
}
ll cmb(ll x, ll y) {
if(x < y) return 0;
return fac[x] * inv[y] % mod * inv[x - y] % mod;
}
int main()
{
//freopen("in.txt", "r", stdin);
scanf("%d", &n);
init();
ll a0 = cmb(4, 1);
for(int i = 0; i < n; ++ i) {
int x;
scanf("%d", &x);
cnt[x] ++;
}
for (auto it: cnt) {
a[it.second] ++;
}
for (int k = 1; k <= n; ++ k) {
ll ans = 0;
for (auto it: a) {
ll ci = it.first, t = it.second;
ll ret = (cmb(n, k) - cmb(n - ci, k) + mod) % mod;
ret = ret * fac[n - k] % mod * fac[k] % mod * inv[n] % mod;
ret = (ret * t) % mod;
ans = (ans + ret) % mod;
}
printf("%lld\n", ans);
}
return 0;
}