Yokohama 2018
Educational Codeforces Round 85
Educational Codeforces Round 59
题目连接
Educational Codeforces Round 59
A
思路
直接拆成2部分,第一部分一个数,第二个部分n个数,考虑相等的情况输入NO,其他为YES
代码实现
1 | #include<bits/stdc++.h> |
Codeforces Round #632 (Div. 2)
题目链接
Codeforces Round #632 (Div. 2)
当时被C题卡了很久,最后20分钟把D的思路想好了却想不到把答案输出的方法,还是思维转变不够快的原因
A
思路
构造题,发现只要构造出
wb
bw
这种[2,2]的形状就可以了
代码实现
1 | #include<bits/stdc++.h> |
POJ-3046-DP
HDU-6578
Codeforces Round #631 (Div. 2)-E
思路
首先要明白b数组,其实就是a数组的异或前缀和,那么要怎么保证异或递增?选的数拆成二进制之后肯定需要位数递增才行,所以我们考虑把d拆成2进制,分成很多块儿,就是这样
[1],[10,11],[100,101,110,111],[1000,….],….
分成上面这样的块,然后从这里面找序列就可以了,然后发现这些块的大小是1 2 4 8 16这样的,然后问题就变成了从x个块中分别取1,2,3,4,5~x个数,然后得到的sum,发现这些数都是2的次幂对吧,我们就找它的系数。它的系数应该怎么找的?考虑当$2^k$为最高的位置时,例如$2^2$在第三位的时候,前面可以有$[2^0,2^1,2^2]$这样如果在第二位就有$[2^0,2^2]与[2^1,2^2]$,然后它的系数就是在它前面的和。接下来这样还是不太好求它的系数,但是我们发现如果从低到高的求系数的话,就可以使用前面的信息,例如当我求出$2^1$的系数为2,也就是$[2^0,2^1]以及[2^1]$本身,还有$2^0$的系数为1,也就是[2^0]自身,那么$2^2$的系数就相当于在它前面出现过的序列相加啊,也就是$[2^0,2^1],[2^1],[2^0]$的后面加上$[2^2]$,也就变成$[2^0,2^1,2^2],[2^1,2^2],[2^0,2^2]$所以我们可以直接递增的求出系数6来。当然它可能不一定是整块,最后剩余的部分怎么考虑?前面有x-1块,处理完后,我们就在这些序列的后面直接加上yu的话,也就是多了这些序列*yu的序列,然后还有后面一部分自成序列的情况,也就是再+yu即可。
poj-3450-后缀数组
poj-2774-后缀数组
题目连接
Height数组
在之前的博客中已经说了后缀数组的具体算法以及如何求出sa数组,但是求出sa之后我们需要学习如何运用sa数组。
第一个运用当然就是height数组了,他表示的意思是
height[i]表示第i小的后缀串与第i-1小的后缀串的最长公共前缀(如图)
如果能够求出这个数组我们就能够在O(n)时间内求出最长公共子串了。
观察上面那个图,我们发现height有一个规律,它的数是3 2 1 0 3 2 1这样的数,然后我们思考,为什么会这样?我们看第一个3的地方是aabaaaab与aab的最长公共前缀,然后如果我们把它去掉第一个字母,哎就变成abaaaab和ab,是不是有些规律?我们就可以用这个规律来求出我们的height数组。
定义一个数组H[i]=height[rk[i]],也就是从i位置的后缀与在sa数组中排名比他小一名的字符串的最长公共前缀,如果我们从1-n的往后求H[i],就很惊讶的发现,竟然就是我们刚刚模拟的过程,所以这样我们就可以得到height数组了1
2
3
4
5for(int i=1,j=0;i<=n;i++){
if(j)j--;
while(s[i+j]==s[sa[rk[i]-1]+j])j++;找出最长的,然后再递减的过程
h[rk[i]]=j;
}