AtCoder Regular Contest 151补题
AtCoder Regular Contest 151
A. Equal Hamming Distances
简单题,注意下答案需要字典序最小即可
#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define ll long long
signed main()
{
int n;
string a, b;
cin >> n >> a >> b;
int cnt(0);
rep(i, 0, n - 1) if (a[i] != b[i]) cnt++;
if (cnt % 2) cout << -1 << endl;
else
{
string ans(a);
int s1 = 0, s2 = 0; cnt /= 2;
rep(i, 0, n - 1)
{
if (a[i] != b[i])
{
if (a[i] == '0')
{
if (s1 < cnt) s1++;
else
{
ans[i] = b[i];
s2++;
}
}
else
{
if (s2 < cnt)
{
s2++;
ans[i] = b[i];
}
else s1++;
}
}
else ans[i] = '0';
}
cout << ans << endl;
}
}
B. A < AP
知识点:计数,连通块
复杂度:\(O(n)\)
一开始被题目吓住了,以为要上带权并查集,后来发现只需要维护连通块的个数即可
枚举 \(A\) 中第一个满足 \(A_i<A_{P_i}\) 的位置
那么对所有的 \(1\) 到 \(i-1\) 都要满足 \(A_i=A_{P_i}\)
我们将之前的 \(j\) 和 \(p_j\) 使用并查集合并
那么此时符合题意的数列个数为 \(C_m^2×m^{cnt-2}\)
\(cnt\) 为连通块个数
注意 \(i\) 和 \(p_i\) 可能一开始就连通,所以要用并查集维护
#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define per(i,r,l) for(int i=r,_##i=l;i>=_##i;i--)
#define ll long long
#define fi first
#define se second
#define endl '\n'
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;
const int mod = 998244353;
const int N = 2e5 + 5;
int f[N];
void init(int n) { iota(f, f + n + 1, 0); }
int find(int u)
{
if (f[u] == u) return u;
return f[u] = find(f[u]);
}
bool link(int u, int v)
{
int fu = find(u), fv = find(v);
if (fu == fv) return false;
f[fu] = fv;
return true;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0);
ll n, m;
cin >> n >> m;
init(n);
vc<ll> p(n + 1), pow_m(n + 1);
pow_m[0] = 1;
rep(i, 1, n)
{
cin >> p[i];
pow_m[i] = pow_m[i - 1] * m % mod;
}
ll cm2 = m * (m - 1) / 2 % mod;
int cnt = n;
ll ans = 0;
for (int t = 1; t <= n; t++) if (link(t, p[t]))
{
ans = (ans + cm2 * pow_m[cnt - 2]) % mod;
cnt--;
}
cout << ans << endl;
}
C. 01 Game
显然每一段连续的空位是互相独立的
我们先推导一个结论
对于左右均有 \(0/1\) 的连续空位,
- 0__1 可以填偶数次数
- 0__0 1__1 可以填奇数次数
从边界开始判断
| 0_0 | 0_1 | |
|---|---|---|
| 空格长度 | 可填次数 | 可填次数 |
| 1 | 1 | 0 |
| 2 | 1 | 2 |
| 3 | 1/3 | 2 |
| ... | ... | ... |
那么对于一个 0_1 段来说
如果我在中间插入一个 0[1],那么我们会得到一对更短的 0_0 串和 0_1 串
总操作次数为: 奇数 + 偶数 + 1 = 偶数对于一个 0_0 段来说
如果我在中间插入一个 0,那么我们会得到一对更短的 0_0 串
总操作次数为: 奇数 + 奇数 + 1 = 奇数
如果我在中间插入一个 1,那么我们会得到一对更短的 0_1 串
总操作次数为: 偶数 + 偶数 + 1 = 奇数
由数学归纳法可证明上述结论
此时中间一段操作次数的奇偶是固定的,
我们只需要考虑两侧可能存在的 __0 和 1__ 串,
由于是博弈题,我们先考虑更加对称的情况,
PS:下述情况中,左右端空格数均大于1,其他情况十分容易推导,就不再赘述
- 显然,如果左右端空格数相同,无论是 __0...1__ 还是 __0...0__ 串都会增加偶数次操作[2],
此时答案只与中间操作次数的奇偶有关
自然而然的,我们就考虑先手修正到对称状态的情况
- 如果,左右端空格数相差超过1,
那么无论中间操作次数的奇偶性如何,先手都可以修正到偶数次操作次数,并且左右端空格数相同
- _ _ _ 1 _ 1 _ _ _ _ _
_ _ _ 1 _ 1 _ 1 _ _ _- _ _ _ 1 1 _ _ _ _ _
_ _ _ 1 1 _ 0 _ _ _
如果,左右端空格数相差等于1
- 此时如果中间操作次数为偶数,那么先手必然可以修正到左右端空格数相同,因为 01 可以相邻
- _ _ 0 _ _ 1 _ _ _
_ _ 0 _ _ 1 0 _ _ - _ _ 0 _ _ 0 _ _ _
_ _ 0 _ _ 0 1 _ _
- 如果中间操作次数为奇数
假设左端空格有 x + 1 个,右端空格有 x 个
那么如果先手要在 这两段空格中填数,就只能填在左边第 x 个空上,并且只能填与 x+2 位置上相反的数
否则都会转化成上述中的先手必胜态
则情况转化成谁第一个填到最左端或最右端的空谁赢
显然 x 为奇数,先手必败
#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define per(i,r,l) for(int i=r,_##i=l;i>=_##i;i--)
#define ll long long
#define fi first
#define se second
#define endl '\n'
#define pll pair<ll,ll>
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;
void pr(bool fi_win)
{
cout << (fi_win ? "Takahashi" : "Aoki") << endl;
}
signed main()
{
ios::sync_with_stdio(0), cin.tie(0);
ll n, m; cin >> n >> m;
vc<pll> x(m + 1);
rep(i, 1, m) cin >> x[i].fi >> x[i].se;
int ans = 0;
rep(i, 2, m) if (x[i].se == x[i - 1].se) ans ^= 1;
if (m == 0) pr(n % 2);
else if ((x[1].fi == 1 || x[1].fi == 2) && (x[m].fi == n || x[m].fi == n - 1))
{
if (x[1].fi == 2) ans ^= 1;
if (x[m].fi == n - 1) ans ^= 1;
pr(ans);
}
else if (x[1].fi == 1 || x[1].fi == 2 || x[m].fi == n || x[m].fi == n - 1) pr(1);
else if (!ans && abs(n - x[m].fi + 1 - x[1].fi) == 0) pr(0);
else if (ans && abs(n - x[m].fi + 1 - x[1].fi) == 1)
pr(min(x[1].fi, n - x[m].fi + 1) % 2 == 0);
else pr(1);
}
D. Binary Representations and Queries
知识点:高维前缀和的可互换性
复杂度:\(O(n*2^n)\)
完全不会,被学长教会的
我们可以视原题有一个 n 维的数组,
那么对于操作 \(X_i\) \(Y_i\),我们可以认为是在第 \(X_i\) 维上做前缀和(\(Y_i=0\))或后缀和(\(Y_i=1\))
那么对于不同的 \(X_i\) 来说,操作的顺序是可以互换的
对于相同的 \(X_i\),我们可以用两个二维的单位向量来模拟第 \(X_i\) 维上的操作结果
所以我们开一个桶分类所有的操作,分别对于不同的 \(X_i\) 模拟操作即可
#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(int i=l,_##i=r;i<=_##i;i++)
#define per(i,r,l) for(int i=r,_##i=l;i>=_##i;i--)
#define ll long long
#define fi first
#define se second
#define endl '\n'
#define pll pair<ll,ll>
#define pii pair<int,int>
#define db(x) cout<<#x<<'='<<x<<' '
#define deb(x) cout<<#x<<'='<<x<<endl
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;
const int mod = 998244353; //1e9 + 7;
const int N = 1e5 + 5;
int n, q;
ll a[1 << 18];
signed main()
{
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> q;
rep(i, 0, (1 << n) - 1) cin >> a[i];
vc<int> p[20];
rep(i, 1, q)
{
int x, y; cin >> x >> y;
p[x].push_back(y);
}
rep(i, 0, n - 1)
{
pii x = { 1,0 }, y = { 0,1 };
for (auto t : p[i])
{
if (t) x.fi = (x.fi + y.fi) % mod, x.se = (x.se + y.se) % mod;
else y.fi = (y.fi + x.fi) % mod, y.se = (y.se + x.se) % mod;
}
rep(j, 0, (1 << n) - 1)
{
if (j & (1 << i))
{
int mi = j ^ (1 << i), ma = j;
ll a0 = a[mi] * x.fi + a[ma] * x.se;
ll a1 = a[mi] * y.fi + a[ma] * y.se;
a[mi] = a0 % mod;
a[ma] = a1 % mod;
}
}
}
rep(i, 0, (1 << n) - 1) cout << a[i] << " \n"[i == _i];
}
AtCoder Regular Contest 151补题的更多相关文章
- AtCoder Regular Contest 128 部分题题解
关于鄙人罚坐两小时那件事...该开始看A题,这不就是个DP记录路径吗?Wrong了,嗯,我没用double,又Wrong,怎么回事,使劲检查自己的算法和细节问题,一个小时过去了,...这没错啊,又反复 ...
- Atcoder Regular Contest 060 F题第一问答案证明
一切的开始 令 \(x\) 为字符串,\(p\) 为正整数.如果对于满足 \(0\le i<|x|−p\) 的任何整数 \(i\) 满足 \(x[i]=x[i+p]\),则 \(p\) 称为 \ ...
- AtCoder Regular Contest 092
AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...
- AtCoder Regular Contest 102
AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...
- AtCoder Regular Contest 096
AtCoder Regular Contest 096 C - Many Medians 题意: 有A,B两种匹萨和三种购买方案,买一个A,买一个B,买半个A和半个B,花费分别为a,b,c. 求买X个 ...
- AtCoder Regular Contest 097
AtCoder Regular Contest 097 C - K-th Substring 题意: 求一个长度小于等于5000的字符串的第K小子串,相同子串算一个. K<=5. 分析: 一眼看 ...
- AtCoder Regular Contest 098
AtCoder Regular Contest 098 C - Attention 题意 给定一个只包含"E","W"字符串,可以花一的花费使他们互相转换.选定 ...
- Atcoder regular Contest 073(C - Sentou)
Atcoder regular Contest 073(C - Sentou) 传送门 每个人对开关的影响区间为a[i]--a[i]+t,因此此题即为将所有区间离散化后求所有独立区间的长度和 #inc ...
- AtCoder Regular Contest 061
AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...
- AtCoder Regular Contest 094 (ARC094) CDE题解
原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...
随机推荐
- thinkphp5.1打印SQL语句
最近在写tp框架搭建的小玩具,有时候我们需要查看SQL语句.所以就诞生了这篇随笔,命令如下: $xxx=db('xxx')->where('x',xx)->select(); $sql=D ...
- Solutions:网站搜索 - Elastic Site Search
- Solutions:应用程序性能监控/管理(APM)实践---python/flask
本文部分内容转载自:https://blog.csdn.net/UbuntuTouch/article/details/102844900 官方文档:https://www.elastic.co/gu ...
- Portainer 安装MySQL并开启远程访问
进入到 Portainer 页面,选择左边的 Containers 选项,单击上方的 Add container 按钮转到如图所示的页面: 1.在 Name 一栏中输入容器名字: 2.在 Image ...
- Jupyter notebook导入Pycharm项目的.py文件里的模块及方法
Jupyter notebook导入Pycharm项目种的.py文件里的模块及方法 需要在Jupyter notebook里调用自己写的代码,过程如下. 首先在Pycharm里写好一个文件,例如DCC ...
- Qemu/Limbo/KVM镜像 Ubuntu 22.04 精简版,可运行Windows软件,内存占用不到200M
镜像特征: Ubuntu 22.04系统 内置Wine 7.8,可运行大量Windows 软件 高度精简,内存占用仅200M不到. 自制UI,Windows3.1风格. 完全开源 镜像说明: 用户名为 ...
- PHP全栈开发(三):CentOS 7 中 PHP 环境搭建及检测
简单回顾一下我们在(一).(二)中所做的工作. 首先我们在(一)中设置了CentOS 7的网络. 其实这些工作在CentOS 6中都是很容易的,因为有鸟哥的Linux私房菜这样好的指导. 但是这些操作 ...
- HDU2041 超级楼梯 (线性DP)
fn[i]表示走上第i级台阶的所有走法. 方程:fn[i]=fn[i-1]+fn[i-2]; 1 #include<cstdio> 2 #define MAXN 40 3 using na ...
- 巧用VBA实现:基于多个关键词模糊匹配Excel多行数据
在用Excel处理实际业务中,我们会碰到如下场景: 1.从一堆人名中找到包含某些关键字的名字: 2.从银行流水文件中根据[备注]字段找到包含某些关键字的,统一识别为[手续费业务]等. 这本质说的都是一 ...
- Filter 筛选器(三)之 自定义一个启动事务的 TransactionScopeFilter
如果一个方法内有多个写入操作,比如 写入A表,然后用A表的自增id 去写入B表,假如A表写入成功,但B表因为某种原因写入失败!(这就导致A表写入了脏数据) 这时候 我们可以自定义 一个Filter 进 ...