致敬先辈!
不过,还有就是,明天,我的最后一个完整的 O I OI OI 赛季就正式开始了。
从 2023-05-20 开始,走过了多久呢?又还要走多久呢?或者,又还能走多久?
AT_arc151_b ARC151B A < AP
原题链接:ARC151B A < AP
分析
别急,它好像每次只关心两个位置。
所以,我不放进行一些比较好看的表示,设 d p i dp_{i} dpi 表示对于所有 j < i j < i j<i 的 j j j,都有 A j = A P j A_j=A_{P_j} Aj=APj,而在 i i i 位置上有 A i < A P i A_{i}<A_{P_i} Ai<APi,那么,每次计算大概是一个,别急,这个真的可以方便地转移吗?
难道说我建一个图,每次再添加边,拿一个并查集维护吗?
我感觉这个式子在一些方面是对的。
真的是建模😭
为啥每次都想不到正解呢?
哦,有一个 A i < A P i A_i<A_{P_i} Ai<APi 就有一个 A i > A P i A_i>A_{P_i} Ai>APi,减去相等的就行了😭
那么,我们建图,有多少个连通块,就有多少个可能的取值。
正解
cpp
#include <bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;
const int N = 200005;
int n, m, p[N];
int qpow(int a, int b){
int res = 1;
while (b){
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int fa[N];
bool vis[N];
int find(int x){
return fa[x] == x ? fa[x] : fa[x] = find(fa[x]);
}
void merge(int x, int y){
x = find(x);
y = find(y);
if (x == y)
return ;
fa[x] = y;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i =1; i <= n; i++){
fa[i] = i;
}
for (int i = 1; i <= n; i++){
cin >> p[i];
merge(i, p[i]);
}
int cnt = 0;
for (int i = 1; i <= n; i++){
vis[find(i)] = true;
}
for (int i = 1; i <= n; i++){
cnt += vis[i];
}
cout << (qpow(m, n) - qpow(m, cnt) + mod) % mod * qpow(2, mod - 2) % mod;
return 0;
}
初赛日 五味杂陈
AT_arc151_c ARC151C 01 Game
原题链接:ARC151C 01 Game
分析
这场可以啊,有数数,还有博弈论!写一下这个博弈论吧。
要凑的就是 0 1 的状物,所以,双方都会这么干,然后,一旦出现什么之类的东西,那么,就有一方具有必胜策略了。
我们来细想一下......
别急,难道是看 m − 1 m-1 m−1 的奇偶性吗?
并非,所以,应该是两边是 0···0 的,Takahashi 必胜;对于两边是 0···1 的,Aoki 必胜。
咋是 Nim 博弈啊😭
正解
cpp
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
long long n, x[N];
int m, y[N];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
x[0] = 0;
x[m + 1] = n + 1;
for (int i = 1; i <= m; i++){
cin >> x[i] >> y[i];
}
long long sg = 0;
for (int i = 0; i <= m; i++){
long long len = x[i + 1] - x[i] - 1;
if (i == 0 && i == m){
sg ^= len % 2;
}
else if (i == 0 || i == m){
sg ^= len;
}
else if (y[i] == y[i + 1]){
sg ^= 1;
}
}
if (sg != 0)
cout << "Takahashi";
else
cout << "Aoki";
return 0;
}