Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)
本文共 7616 字,大约阅读时间需要 25 分钟。
A题 (签到)
思路:根据题意,最终操作后,奇数不会变,偶数都会减1
#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈#include #include #include #include #include #include #include #include #include #include
B题 (签到)
题意:把一个数组分成k段,每段贡献为区间最大值,求总贡献最大值
思路:找出前k大的元素下标,然后下标按递增排序
PS:这题自己属实脑瘫= =、,在输出区间长度的时候,总是细节出问题,wa了三发
#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈#include #include #include #include #include #include #include #include #include #include
C题 (双指针+坑)
题意:给定一个数列,把它分成3段 ,可以是空段。记每段的区间和为a b c, (a区间从首项开始 b为中间段 c末项结束) 问满足a==c 且a最大的分法下,a为多少。 (a c有可能取0)
思路:双指针,p1 p2刚开始分别指向首项和末项,代表左区间和右区间的最远扩展点。 然后不断向中间扩展 ,细节判断见代码
#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈#include #include #include #include #include #include #include #include #include #include
D题 (字符串水题)
题意:给定两个字符串,我们能进行三种操作:第一种,将 a[i] 和 b[i] 的单个字符交;第二种,将 a[i] 和 a[n-i+1] 的单个字符交换;第三种,将 b[i] 和 b[n-i+1] 的单个字符交换。但是题目的要求是,让我们先做预处理替换a中的字符,再进行如上三种操作,能让字符串 a == b ,求预处理的次数。
思路:其实看懂了样例就不难,纯粹的模拟题。
我们每次需要比较a[i] a[n+1-i] b[i] b[n+1-i] 这4个元素 。看它们能不能两两配对相等 。出现诸如 a a b b / a b a b /这些情况 ,因为这些位置其实是互通的。
我们分两种情况讨论:
1、 b[i]==b[n-i+1]: 此时如果 a[i]!=a[n-i+1] ,操作次数就+1,否则+0
(这里我真傻,第一次写的时候不等的情况次数+2去了 = =、 又是因为太傻逼wa了)
2、 b[i]!=b[n-i+1] : 先看a[i] 会不会跟两个都不相等,如果会,次数+1 ;再看a[n-i+1] 会不会跟两个都不相等,如果会,次数+1。 这里有个特殊情况,如果a[i] a[n-i+1]都跟其中一个相等,可能是 a a /a b这种情况,操作次数得加1.
#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈#include #include #include #include #include #include #include #include #include #include
E题 (DFS)
这应该是写过最水的E题了…
题意:给定一棵n顶点的有根树,1为根。给出q个询问,每次询问以u为根的子树,dfs序第k个节点编号。 dfs过程优先遍历序号小的孩子节点。若不存在输出-1
(1<=n,q<=2e5)
思路:按照题目要求dfs一遍,order存dfs序,Hash[i]存第i个顶点在dfs序数组中的下标。num[i]存以i为根的树,有几个顶点。
#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈#include #include #include #include #include #include #include #include #include #include
F题 (双向dfs搜索+记忆化搜索)
题意:输入n,m,k,给出一个n*m的矩阵网格,每个格子有权值,从(1,1)一路异或到(n,m),只能向右或向下走,求到达(n,m)时,异或值等于k有多少种路径。
(1<=n,m<=20 0<=a[i][j],k<=1e18 )
异或性质:
1、a ^ b ^ a=b ^ a ^ a=b ( 一个数对另一个数异或2次 得原数)
2、a^ b^ c^ d^ e…进行异或运算,顺序不影响结果
3、若a ^ b=c 则 a ^ c=b 且 b ^ c=a
//扩展 a
bc
d…x=y 则y替换左边任何一个 等式都成立
PS:这题一开始联想到AC自动机上状压dp,也想用类似的状压dp方法做。
但是这里的状态有1e18,太大了,所以考虑用map. 感觉思路没啥问题。
没想到提交后mle了 淦。后来用滚动数组优化了一维,居然还是mle。太草了! 可能是map耗内存太大了吧。
AC思路:dp不行,那只能记忆化搜索了。但是朴素的搜索估计会tle或mle 。大佬的题解里用了一个高级的玩意儿,双向搜索。以知了出发点和目的点的状态,分别从出发点开始dfs,搜到中间位置则停下 。再从目的点开始dfs,带着状态搜到中间点记录答案。
关于这里双向搜索,我说一下自己的理解: 从起点到终点,假设得到k的异或路径经过的数依次是x1,x2,x3,x4…xf 。那么只要在搜索过程中让这些数参与异或就一定可以得到k,我们假设在中间点经过的数为Xm,根据异或性质 ,x1,x2,x3…k…xf参与异或得到的一定是Xm ,所以双向搜索过程中,搜到中间的时候用k去参与异或得出这个Xm就可以了。
//#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈#include #include #include #include #include #include #include #include #include #include
上mle的代码 ,思路我感觉是ok 的qaq
//#pragma comment(linker, "/STACK:102400000,102400000")///手动扩栈#include #include #include #include #include #include #include #include #include #include
转载地址:http://xwjyk.baihongyu.com/