摘要:
#字符串 ##双哈希 Birthday Cake 给n个字符串,问每个字符串前后缀相等时,中间的串与其他字符串相等的个数。 #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll, ll> 阅读全文
摘要:
题目链接 #概念(摘自进阶指南) 给定一个字符串S[1~n]我们不断把它的最后一个字符放到开头,最终会得到n个字符串,称这n个字符串是循环同构的。这些字符串中字典序最小的一个,称为字符串S的最小表示。 #解题思路 模版题,直接算出两个字符串的最小表示比较一下就行了。 #代码 const int ma 阅读全文
摘要:
题目链接 #解题思路 求出两个字符串代表的树的最小表示,进行比对就能得到答案,为了方便处理,给他设定一个根,即在开头加一个0,当然在结尾也要再加上一个1。 关于最小表示的求法,每次都求出子树字典序最小的组合方式,然后向上合并为字典序最小的组合方式即可,显然可以用递归来完成。 #代码 const in 阅读全文
摘要:
题目链接 #基本思路 这道题最基本的想法就是一次寻找每个区间,对于每个区间,用二分来判定其最大长度。每次check的时候,对区间排序,不断取出不大于m对最大值与最小值求值即可。 然后你就喜提TLE了,笑如果用倍增来代替二分的话能过,不过其实倍增最坏复杂度和二分一样,应该是数据没有刻意来卡倍增。下面先 阅读全文
摘要:
题目链接 #解题思路 将所有的字符串编码看成是一棵trie,因为所有的字符串都不互为前后缀,所以每一个字符串都末尾都位于trie的叶子结点上。 因为要确保总长度最小,所以对于出现次数越多的字符串,其叶子在trie上的深度就越浅,那么出现次数越少的字符显然其叶子深度也就越深。所以可以用出现次数做权值, 阅读全文
摘要:
题目链接 #解题思路 询问区间小于某个数个个数显然可以用二分来做,但是如果配合上区间加法就有些复杂了。即使对每个区间排序,用标记来代替修改,但是对于边缘的数据来说,需要暴力修改,而暴力修改后打破区间的有序性。那就暴力修改之后再重新排序~~(没错,就是这么狠(笑~~ #代码 const int max 阅读全文
摘要:
题目链接 #解题思路 分块模版i #代码 const int maxn = 5e4+10; int n,sz,num,a[maxn],ls[maxn],rs[maxn],belong[maxn],lazy[maxn]; void build() { num = (n+sz-1)/sz; //分块大小 阅读全文
摘要:
题目链接 #解题思路 题面差不多已经用的算法写到脸上了,不过有个问题就是怎么判断枚举的区间符合条件,如果直接暴力的话复杂度就要乘上q,但是如果用一个变量来计数的话,就能让时间复杂度降下来。 #代码 const int maxn = 1e5+10; int n,m,a[maxn],cnt[maxn]; 阅读全文
摘要:
题目链接 #解题思路 一共就4个数,分3步,每次让两个数通过乘或加合并成一个数,数据范围很小,所以直接大力搜就是了。 #代码 ll a[4], ans = LLONG_MAX; bool vis[maxn]; string s; void dfs(int p) { if (p==3) { for ( 阅读全文
摘要:
题目链接 #解题思路 因为要从4列中各选1个数使和等于0,所以可以枚举任意两列和剩余的两列,那么前者的数量乘以后者中前者的相反数的数量就是本题答案。不过这个得用哈希但是好像会被卡的样子,那么可以把前者都存起来,然后枚举后者,通过二分计算数量。 #代码 const int maxn = 4e3+10; 阅读全文