2020牛客NOIP赛前集训营-提高组(第一场) T2 牛牛的猜球游戏
题目链接: 牛客原站
通过记录:
题目链接2:T277380 牛牛的猜球游戏(被我们搬到洛谷力):
洛谷搬运
题目描述
有十个数 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 0,1,2,3,4,5,6,7,8,9 0,1,2,3,4,5,6,7,8,9 依次排列为初始序列,告诉你一个长度为 n n n 的操作表,每次操作为交换处于 a 、 b a、b a、b 两个位置的数。接下来有 m m m 个询问,对于每一个询问有两个数 l , r l,r l,r ,请回答从初始序列,直接从操作表单的第 l l l 操作一直执行到 r r r次操作,并输出此时最终序列。
算法思路
好怪好怪,我直接暴力枚举薄纱捏。
啊啊啊, n 、 m n、m n、m 怎么都是1e5级别的啊。线性都过不了咩?
诶,那么不就很明显了,因为你始终要处理 m m m 次询问,那么算法时间复杂度的理论下限都是1e5,所以处理l~r的事情要么 O ( 1 ) O(1) O(1) 过,要么 O ( l o g ( r − l ) ) O ( s q r t ( r − l ) O(log(r-l)) O(sqrt(r-l) O(log(r−l))O(sqrt(r−l) 选吧!!!
是的,你没想错,这还真的有O(1)的算法,但是log级、根号级的也能过。来康康同机房大佬们的乱搞捏:
分块做法 来源if-OF。 回滚莫队 来源:Gmt丶FFF 。
然后我这个蒟蒻,考完之后跑去听评讲,就去调了标准bug了。搞了半天,发现这题想清楚后居然如此简单。
来想一想一个简单的事情,如果我做了好几次操作,但是如果我知道他操作的最后序列,那我就可以直接调过去。
啊这不是SB吗?我要知道他的最终序列我还写个啥啊。但事实上,你知道你在读入操作表的时候,是可以得到从初始状态一直操作到现在的序列滴。
所以我们记下一个“前缀序列”,那么就可以解决所有由1开始的问题。
但是这还不够! (这不显然吗) 我们要想想这个换的本质,实际上原题中也提示到了“换的是杯子,而不是球”!是的,我把里面的球不要说是1,2,3,4,5,而是A,B,C,D,E,这个事情就好理解了。那我们这个“序列”;里存的这个值有什么意义呢?是的,就是初始序列的杯子序号。
也就是说,我们初始序列比如是ETYMK,而前缀序列是45231,那么它所表达的答案就是MKTYE,诶,是不是好理解了一点。
那也就是说我们理解到了,前缀序列并不只是记录当前状态,还能是一种可用于转移的东西,等价于“一次操作”。(这里直接看代码也还不错)
诶?我们把得到的序列可以视为一种操作诶,那我们是不是只要两个状态:原始序列+运算序列,就可以把询问的答案干出来了捏?
是的捏!我们容易想到,把l-1号的序列或r号的序列作为初始序列,在从蝙蝠侠妈妈那里搞到一手运算序列就算出来了。
啊对啊,这个运算序列不能去阴间找,得算出来 (但是蝙蝠侠的妈妈就没那么幸运了) 。我们一想,奥,另一个就是啊。但又不完全是。因为,是减法!!!
啊对,我们现在考虑的不能再是“执行操作表”的运算了,应该用“还原”。这就像求一个数列 i j i~j i j 的和,那就是 s u m [ j ] − s u m [ i − 1 ] sum[j]-sum[i-1] sum[j]−sum[i−1] 。是个恶心的减法。
要求一个还原序列,其实也还好,我们只会算加法,所以要做的事在记录 s u m [ i ] sum[i] sum[i] 时同时记录一个 − s u m [ j ] -sum[j] −sum[j] 。我们还原的思路,就是考虑把一个序列还原回0,也就是 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 0,1,2,3,4,5,6,7,8,9 0,1,2,3,4,5,6,7,8,9 的操作序列。
如果你已经想清楚了刚才“操作”的本质,你也应该发现了,我们在得到“操作前缀序列”(第i位的数为j意味着将原始序列的第j位放入i位)后,只要把本质逆过来再,就是把第刚才你5位在的那个数记回5这种就好。(没懂可以看看代码,挺简洁的)
做到这一步,题目的思路就已经清晰下来了:
首先在读入操作表单时,处理出前缀序列,并根据这个前缀序列得到反向序列(即负前缀序列)。
然后读入询问时,对于每一个询问,直接用 前缀序列r + 负的前缀序列 ( l − 1 ) (l-1) (l−1) 计算答案序列,输出即可。
(啊好吧不是 O ( 1 ) O(1) O(1) 是 O ( 10 ) O(10) O(10) ,但这重要吗?(有点重要))
特殊处理
别把自己搅糊涂了哟。
代码实现
#include<bits/stdc++.h>
using namespace std;#define int long long//管他用不用,开就完事了、、、好像真的不用开int n,m;
int xl[100050][10];//前缀序列
int fxxl[100050][10];//反向序列捏inline int rd()//读入优化真的不是人手一只吗?
{int a=0,f=1;char c=getchar();for(;c<'0'||c>'9';c=getchar()) if(c=='-') f=-1;for(;c>='0'&&c<='9';c=getchar()) a=(a<<1)+(a<<3)+c-'0';return a*f;
}signed main()
{n=rd(),m=rd();for(int i=0;i<10;i++)xl[0][i]=i,fxxl[0][i]=i;//是的捏,0号初始序列就是0,1,2,3,4,5,6,7,8,9for(int i=1;i<=n;i++){int a=rd(),b=rd();for(int j=0;j<10;j++)if(j==a) xl[i][j]=xl[i-1][b];//录入,得到前缀序列else if(j==b) xl[i][j]=xl[i-1][a];else xl[i][j]=xl[i-1][j];for(int j=0;j<10;j++)fxxl[i][xl[i][j]]=j;//得到反向序列,如果上面没懂得,看代码实现可能会更好理解}for(int i=1;i<=m;i++){int l=rd(),r=rd();for(int j=0;j<10;j++)putchar(fxxl[l-1][xl[r][j]]+'0'),putchar(' ');//对l-1的反向序列和r的正向序列相加puts("");//换行}return 0;}
2020牛客NOIP赛前集训营-提高组(第一场) T2 牛牛的猜球游戏相关推荐
- 【2020牛客NOIP赛前集训营-提高组(第一场)题解】( 牛牛的方程式,牛牛的猜球游戏,牛牛的凑数游戏,牛牛的RPG游戏)
未完待续... T1:牛牛的方程式 title solution code T2:牛牛的猜数游戏 title solution code T3:牛牛的凑数游戏 title solution code ...
- 【2020牛客NOIP赛前集训营-提高组(第二场)】题解(GCD,包含,前缀,移动)
文章目录 T1:GCD title solution code T2:包含 title solution code(正解code补充在上面了) T3:前缀 title solution code T4 ...
- 2020牛客NOIP赛前集训营-提高组(第三场)C-牛半仙的妹子Tree【虚树,最短路】
正题 题目链接:https://ac.nowcoder.com/acm/contest/7609/C 题目大意 给出nnn个点的一棵树,mmm个时刻各有一个操作 标记一个点,每个点被标记后的每一个时刻 ...
- 2020牛客NOIP赛前集训营-提高组(第六场)A-袜子分配【组合数学,结论】
正题 题目链接:https://ac.nowcoder.com/acm/contest/7615/A?&headNav=acm&headNav=acm 题目大意 nnn对颜色一样的袜子 ...
- 2020牛客NOIP赛前集训营提高组(第四场)B-色球【链表】
正题 题目链接:https://ac.nowcoder.com/acm/contest/7611/B 题目大意 nnn个杯子,mmm个操作 在第zzz个杯子中依次加入xxx个颜色为yyy的球 在第yy ...
- 2020牛客NOIP赛前集训营-普及组第三场C牛半仙的妹子树
链接:https://ac.nowcoder.com/acm/contest/7608/C 来源:牛客网 牛半仙有 n 个妹子,她们所在的位置组成一棵树,相邻两个妹子的距离为 1. 有 m 个妹 ...
- 2021牛客OI赛前集训营-提高组(第四场) T2空间跳跃
2021牛客OI赛前集训营-提高组(第四场) 题目大意 给你三个整数 n , d , l n,d,l n,d,l, n n n为正整数.负整数或0, d , l d,l d,l为正整数,你现在有一个数 ...
- 2021牛客OI赛前集训营-提高组(第五场)D-牛牛的border【SAM】
正题 题目链接:https://ac.nowcoder.com/acm/contest/20110/D 题目大意 求一个长度为nnn的字符串的所有子串的borderborderborder长度和. 1 ...
- 2021牛客OI赛前集训营-提高组(第五场)C-第K排列【dp】
正题 题目链接:https://ac.nowcoder.com/acm/contest/20110/C 题目大意 一个长度为nnn的字符串SSS,SSS中存在一些???,有N/O/I/PN/O/I/P ...
最新文章
- Thymeleaf 标准表达式语法详解
- 爬虫采集-基于webkit核心的客户端Ghost.py [爬虫实例]
- 用996打败员工,用“奋斗”替代生活
- win32汇编创建线程简单Demo
- java线程代码实现_Java 实现线程的2种方法的具体代码实例
- Python中曲率与弯曲的转换_黎曼几何学习笔记(3)——共形数量曲率与高斯曲率...
- 中国芯片人才大军在哪里?
- 磁盘一把锁一个感叹号_TBase中的一些锁
- 食品级L-天门冬氨酸市场现状及未来发展趋势
- 为virtools写的插件进行一下总结
- C语言中的引用,以及传递引用,数组传递
- ISO8583 报文协议
- sql server中的怎么把数值型转换为字符串
- linux ps命令 详细介绍
- 【leetcode】1849. 将字符串拆分为递减的连续值
- 阳光宽频加密算法破解,找出隐藏真实地址。
- Windows10系统U盘制作
- 基于手机支付方式的电子商务网站
- 小程序----setDate
- 基于安装django报错信息的处理方案