摘要:
直接维护好两个数组就可以了,每次访问得到区间的最小值和最大值。代码如下:#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( 阅读全文
摘要:
要求输出每个单词在不产生歧义的情况下的最短前缀,直接构造出一颗字典树就可以了。先执行插入操作,对每一个单词经过的路径都进行一个自增的操作。再一次搜索每一个单词,当其遇到覆盖次数为一,或者是到了单词末尾就输出。代码如下:#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int N, idx;char s[1005][25], rec[25];struct Node{ int cnt, ch[26];}e[30000 阅读全文
摘要:
这题用匈牙利算法是无论如何也过不了的,边太多了。利用简单的贪心规则,我们每次选取最优的匹配方案来进行匹配,在划分上我们采用工资要求为负值的去寻找工资要求为正值的人。对于一个要求工资比他低的男人来说,其实就是优先最有钱的男人,因为能与之匹配的女生是最多的,在选取女生的时候,就选择满足要求下工资最高的女生,因为这种女生最难满足要求,这一对配对对后面的匹配来说是最优的。女生同理。代码如下:#include <cstring>#include <cstdio>#include <cstdlib>#include <algorithm>#define MA 阅读全文
摘要:
该题就是简单的二维树状数组,保留一份棋盘的最新状态即可,树状数组里面就只保留在原有基础上增加或者减少的某一种饺子的数量。代码如下:#include <cstring>#include <cstdlib>#include <cstdio>using namespace std;char op[5];char G[1050][1050];int cc[1050][1050];// 数组中存储韭菜饺的数量,白菜饺的数量通过总数量减去韭菜饺来求void init(){ int k = 0; // 定义韭菜为1,白菜为0 for (int i = 1; i <= 阅读全文
摘要:
由于只有最多16种组合情况,所以就直接暴力枚举求解。这里题目有个要求就是按照字典序相对较小的输出规则输出,那么我们可以想到在兴趣数相同的情况下要不要去更新最优值,这就牵涉到我们刚开始的时候求解出来的解是否一定是字典序最小的,或则最后求解出来的解就是字典序最小的,我是采用压缩后的二进制数的最高位代表最小的兴趣,所以从最高位通过自减操作能够保证每次得到的该兴趣数的第一个解都是字典序最小的。#include <cstdlib>#include <cstring>#include <cstdio>#include <algorithm>using nam 阅读全文
摘要:
一个网格中的图形,如果其面积只取方格的整数倍的时候,那么我们有如下公式。设面积为Area,多边形内部的整点个数为OnEdge,多边形轮廓线上的整点个数为InSide,那么有公式 Area = OnEdge / 2 + InSide - 1代码如下:#include <cstdlib>#include <cstdio>#include <cstring>using namespace std;int main(){ int T, N; long long int ret, S; scanf("%d", &T); while (T-- 阅读全文