【做题】atc_cf17-final_E - Combination Lock——巧妙转化及图论
题意:给出一个由26个小写字母组成的字符串,可以任意地进行若干个操作,每次操作是让指定区间内的字母变为下一个字母(z变成a)。问是否存在方案使得这个字符串变为回文串。
一开始的想法是构造len/2条模26意义下方程,但由于26不是质数,判断有没有解并不容易。(下文自动省略模26)
我们发现,一次操作对于方程组的影响大概是这样的:

如上图所示,一次对区间[l,r]进行的操作,其中从一端到其关于中点的对称点的区间实质是没有贡献的。(上图中为区间[l,l'])同样地,对于完全位于中点右边的区间,可以将其翻转到中点左边。
因此,所有操作的影响都被移动到了中点左边,则每一条方程都变成了如下形式:k1*x1+k2*x2+...+kn*xn=p。其中,p为常数,且ki为0或1。
而且,每一次操作的影响都是一个区间,所以这就成了一个通过区间操作是一个序列中元素全部变为0的问题。
上述问题简单地说就是,回文串就是左右两边的元素差值为0。所以最终目的就是使这些差值全部变为0。
所以很容易想到对于那个需要变成0的数列差分得到序列a,每一次操作区间[l,r]就是a[l]+1,a[r+1]-1。这等价于令a[l]+a[r+1]一定,然后任意确定a[l]和a[r+1]的值。
同样地,两个操作[l1,r-1]和[l2,r-1]也就是a[l1]+a[l2]+a[r]一定,然后任意确定这三个数的值。
因此,我们可以建一张有len/2+1个点的图,点i的权值为a[i],每一次操作[l,r]就是给点l和点r+1连一条边。则存在方案 <=> 每个连通分量内点权和为0。
上述过程可以用并查集实现。
时间复杂度O(n*α(len))。(下面代码没有按秩合并,时间复杂度为O(n*logn);有代码更优美的实现方式,即计算时保留S的右半部分)
#include <bits/stdc++.h>
using namespace std;
const int N = ;
int n,m,s[N],sum[N],dif[N];
int flag[N];
int get_flag(int pos) {
return flag[pos] == pos ? pos : flag[pos] = get_flag(flag[pos]);
}
void fit(int& x) {
if (x > n/) x = n-x+;
}
int fix(int x) {
if (x<) x = -(-x)%;
x %= ;
return x;
}
int main() {
int l,r;
for (char tmp=getchar();tmp>='a'&&tmp<='z';tmp=getchar())
s[++n] = tmp-'a';
for (int i=;i<=n/;++i)
s[i] -= s[n-i+],dif[i]=s[i]-s[i-],flag[i]=i;
dif[n/+] = -s[n/];
scanf("%d",&m);
for (int i=;i<=m;++i) {
scanf("%d%d",&l,&r);
if (n&) {
if (l == n/+&&r == n/+) continue;
if (l == n/+) l++;
if (r == n/+) r--;
}
if (l<=n/&&r>n/) {
fit(r);
if (l>r) swap(l,r);
r--;
} else {
fit(l);fit(r);
if (l>r) swap(l,r);
}
flag[get_flag(l)]=flag[get_flag(r+)];
}
for (int i=;i<=n/+;++i) sum[get_flag(i)] += dif[i];
for (int i=;i<=n/+;++i) if (fix(sum[i])!=) {
return *puts("NO");
}
puts("YES");
return ;
}
小结:一种重要解题方法就是对题目进行转化。
【做题】atc_cf17-final_E - Combination Lock——巧妙转化及图论的更多相关文章
- (转)poj算法做题顺序
初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. (5)构造法.(poj329 ...
- 最大流 总结&&做题记录
最近一直很忙,为了节省时间,从今以后的题解会 一个专题 写一篇. 刷了一些题后,有了以下总结: 模型要点: 1.构造流量平衡,在满足流量平衡的情况下,找到要让什么最大. 2.一般用于判断性问题,即所有 ...
- AtCoder Grand Contest 11~17 做题小记
原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-11-to-20.html UPD(2018-11-16): ...
- AtCoder Grand Contest 1~10 做题小记
原文链接https://www.cnblogs.com/zhouzhendong/p/AtCoder-Grand-Contest-from-1-to-10.html 考虑到博客内容较多,编辑不方便的情 ...
- 贪心 Codeforces Round #301 (Div. 2) A. Combination Lock
题目传送门 /* 贪心水题:累加到目标数字的距离,两头找取最小值 */ #include <cstdio> #include <iostream> #include <a ...
- CodeM美团点评编程大赛复赛 做题感悟&题解
[T1] [简要题意] 长度为N的括号序列,随机确定括号的方向:对于一个已确定的序列,每次消除相邻的左右括号(右左不行),消除后可以进一步合并和消除直到不能消为止.求剩下的括号的期望.\(N \l ...
- 【做题】BZOJ2342 双倍回文——马拉车&并查集
题意:有一个长度为\(n\)的字符串,求它最长的子串\(s\)满足\(s\)是长度为4的倍数的回文串,且它的前半部分和后半部分都是回文串. \(n \leq 5 \times 10^5\) 首先,显然 ...
- Sam做题记录
Sam做题记录 Hihocoder 后缀自动机二·重复旋律5 求一个串中本质不同的子串数 显然,答案是 \(\sum len[i]-len[fa[i]]\) Hihocoder 后缀自动机三·重复旋律 ...
- 退役III次后做题记录(扯淡)
退役III次后做题记录(扯淡) CF607E Cross Sum 计算几何屎题 直接二分一下,算出每条线的位置然后算 注意相对位置这个不能先搞出坐标,直接算角度就行了,不然会卡精度/px flag:计 ...
随机推荐
- Js闭包学习笔记
好多内容摘抄了大神的博客内容,只为分享记录.如有冒犯,请见谅 参考文章 http://www.cnblogs.com/libin-1/p/5962269.html http://www.cnblogs ...
- <9>cc.Sprite组件
1.精灵 精灵(Sprite)是Cocos系列的核心概念之一,是Cocos Creator最常用的显示图像的组件. 游戏中显示一个图片,我们就可以把这个叫做”精灵” sprite,这只是简单理解概念. ...
- os.system
python os.system os.system()函数在不同的系统下可以实现不同的作用 一.window下: os.system("ping www.baidu.com" ...
- web api 跨域访问
在工程中 Install-Package Microsoft.AspNet.WebApi.Cors 在 webapiconfig.cs中 config.EnableCors(); 在 控制器中, [E ...
- 使用函数式编程消除重复无聊的foreach代码(Scala示例)
摘要:使用Scala语言为例,展示函数式编程消除重复无聊的foreach代码. 难度:中级 概述 大多数开发者在开发生涯里,会面对大量业务代码.而这些业务代码中,会发现有大量重复无聊的 foreach ...
- MCMC算法深入理解
MCMC(Markov Chain Monte Carlo),即马尔科夫链蒙特卡洛方法,是以马尔科夫平稳状态作为理论基础,蒙特卡洛方法作为手段的概率序列生成技术. MCMC理论基础 如果转移矩阵为P的 ...
- isIos
function IsIOS() { if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) { return true } else { r ...
- mybatis源码解析1--前言
在开始分析mybatis源码之前,需要定一个目标,也就是我们不是为了读源码而去读,一定是带着问题去读,在读的时候去寻找到答案,然后再读码的同时整理总结,学习一些高级的编码方式和技巧. 首先我们知道my ...
- CATALINA_OPTS和 JAVA_OPTS区别
在Tomcat的catalina.sh文件中的启停server脚本中都应用到了两个变量: CATALINA_OPTS和JAVA_OPTS.用于保存Tomcat运行所需的各种参数. 他们在文件中的注释如 ...
- 一个讲课截屏 清明DAY2
灰常混乱 放弃吧........ 不断做平方差公式 到i时,前面已经求出之前数字的逆元了 r是一个比i小的数 第四行×i,r 的逆元 BSGS 暴力枚举枚举到Φ(m)个