摘要:
这题主要是要将两个串的比较进行优化,不能够每次都从起始位置进行匹配。这里用到了线段树进行优化,将每段区间的hash值进行更新和维护,通过找某一点的有连续段最长相同串即可。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>#define MOD 100000003#define T 29LLusing namespace std;typedef unsigned int Int64;// 这里建立棵线段树记录某一短区间的hash值 char s 阅读全文
摘要:
这题是按照解题报告上的思想来写的。觉得这个想法确实是很麻烦。现大概说下思路:首先我们需要通过dp求出每一个点上下左右的延伸距离,这个距离就是连续的1的个数。预处理好这个信息后。我们不是去枚举每个点,而是去枚举每条对角线上的点,按照上面的说法,一条很明显的规则:所有边由1组成的正方形的对角线一定是矩形的对角线,相比N^2的枚举每个点,这个做法有个好处就是减少重复计算。我们的主要思想还是确定一个点为目标正方形的左上角点,然后取右、下的较小值作为其可及域,我们只需要统计这个区域内的点是否能够能够反向覆盖。对于对角线 L, 我们从左上角到右下角进行遍历, 设当前点的坐标为(i, j),对角线坐标是1( 阅读全文
摘要:
这题就是一个数据量大点的a+b+c+d+e = 0的判定,可以用哈希表来做,也可以用来个有序表来寻找解。时间复杂度前者接近O(n^3),后者则为O(N^3).代码如下:哈希表:#include<iostream>#include<map>#define MOD 1000003LLusing namespace std;typedef long long LL;const int N = 205;LL a[6][N];int head[1000005], idx;struct Node{ LL v; int next; }e[40005];void add(LL key) 阅读全文
摘要:
直接维护好两个数组就可以了,每次访问得到区间的最小值和最大值。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;int N, M, seq[50005], Min[50005][20], Max[50005][20];void Minbuild(){ int LIM = (int)log2(double(N)); for (int i = 1; i <= 阅读全文
摘要:
该题时间跨度太大,如果直接把时间建树的话显然内存不足,那么我们考虑到只有10^5朵花,于是要采取离散化,但是如果只是离散化花朵的时间的话,那么当我们去查询某个时间的时候,这个时间点在线段树里面的信息的不存在的,于是也就得不到正确的答案,因此我们要离散化花朵和询问的所有时间,这样信息就完备了。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#include <map>using namespace std;int N, M, ti 阅读全文
摘要:
对于这样一道有着如此强烈限制条件的题目(任意两个点一定有边,而且是单向边),表示拥有各种解法,甚至连随机化的方法的AC率都不会太低。这里考虑到不会存在二个点成环的情况,那么我们要论证的就是三个以上的点成环那么就一定有三个点能够成环。对于N个点成环的情况,我们可以选取连续的三个点,如果两边的两个点的边的方向刚好使得三个点成环的话,那么就说明我们的假设成立,如果不是的话,那么就变成了N-1个点成环,以此类推,就一定能够找到3个构成的一个环。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#inc 阅读全文
摘要:
这题比赛的时候纠结了不少...对于A进制的一个数,先将其左移N位使得其成为一个整数,然后再将这个整数化为B进制的一个数,然后我们只需要考虑这个数是否能够整除A^N即可(因为我们前面左移了N位),我可以将B进制的这个数先进行左移无限位,那么当有A^N 整除 B^INF 时我们就可以将这个除尽,然后我们再将B右移INF位便可以了。这里就把问题转化为了A^N能够整除B^INF进制了,进一步我们可以得到B包含所有A的质因子便为判定条件了。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#includ 阅读全文
摘要:
最后才明白题目的意思可以直接抽象为对于每一位,所有数字的0个数乘以1的个数,再将每一位的数恢复过来。自己的做法也是枚举每一个二进制位,对于已经求了 ai,ai+1...aN-1,aN个数的二进制位之后再用ai-1的这一位的情况来判定这一位会增加多少个1。代码如下:#include <cstring>#include <cstdio>#include <cstdlib>#include <algorithm>using namespace std;typedef long long int Int64;// 1000000 这个数字只有最多19位i 阅读全文
摘要:
这题不要去考虑每一个时刻的情况,而要考虑每一个位在所有时间上的叠加效果。对于长度为Lf的母串和长度为Ls的子串来说,每个字符匹配的长度都是Lf-Ls+1位。代码如下:#include <cstring>#include <cstdio>#include <cstdlib>using namespace std;char f[2000005], s[2000005];int lens, lenf, cnt[30];int main(){ int T, LIM; long long int ans; scanf("%d", &T); 阅读全文
摘要:
将所有括号都找出来,枚举所有的可能,再用strcmp排下序就可以了。标程用到的方法更好,直接标记每个括号属于哪一个括号组,然后直接解压状态即可。代码如下:#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;char s[210], rec[1050][210];int stack[15], top, length, cnt;struct Parentheses{ int l, r;}P[15];void init( 阅读全文