做题反思和总结
Lupin123123
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
[hdu] P7079 Pty loves lines
题目链接经典的求直接交点数的问题之前做过简化版 ,并且安利一下自己的题解如果依旧像之前一样用二维dp[i][j]表示能否达到i条直线,j个交点的情况,将面临运行超时,dp数组存不下的尴尬局面。那么考虑新的做法。考虑讲n条直线划分为若干组,每一组内的直线两两平行且这个组是极大的。设总共分成了 ppp 组,每一组的直线数为 aia_iai,那么交点数就是n(n−1)2−∑i=1kai(ai−1)2\frac{n(n-1)}{2}- \sum_{i=1}^k\frac{a_i(a_i-1)}{2}2n(原创 2021-08-20 01:23:41 · 646 阅读 · 6 评论 -
[hdu] P6964 I love counting
树状数组+trie树。原创 2021-08-14 03:50:46 · 340 阅读 · 0 评论 -
[ZOJ] P3228 Searching the String
ac自动机练手题,可以当成ac自动机不重叠匹配的模板。 题目链接由于有多个模式串要匹配,那么如果用kmp复杂度就是O(qn)O(qn)O(qn),这显然是吃不消的。那么就考虑用多模式串匹配的利器——ac自动机。时间复杂度接近O(n)O(n)O(n)。对于这道题要解决的第一个问题是如何实现不重叠匹配。思考后不难发现,只需记录trie图中的结点所表示的单词上一次在文本串中出现的位置即可。具体表现为下面的代码: void match2(char *s) //不可重叠 { int len=strle原创 2021-08-13 19:43:36 · 154 阅读 · 0 评论 -
[Luogu] P1083 [NOIP2012 提高组] 借教室(线段树)
题目链接最小值线段树模板题。按顺序更新区间,维护最小值。最小值小于0的时候就找到矛盾了。复杂度O(mlogn)O(mlogn)O(mlogn)完整代码:#include<bits/stdc++.h>#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#define INF 0x3f3f3f3ftypedef long long ll;const int maxn = 1e6+5;using namesp原创 2021-08-11 22:32:44 · 145 阅读 · 0 评论 -
[Luogu] P1108 低价购买
题意:求一个序列中最长下降子序列的方案数,看上去一样的方案只算一次。设f[i]表示1…i中以a[i]结尾的最大下降子序列的方案数,dp[i]表示以a[i]结尾的最大下降子序列的长度。如果是不要求把看上去一样的方案去掉,可以按如下的代码计数: for (int i=1; i<=n; i++) { if (dp[i]==1) f[i]=1; for (int j=1; j<=i-1; j++) if (a[i]<a[j] && dp[i]==dp[原创 2021-08-08 17:35:20 · 112 阅读 · 0 评论 -
[Luogu] P1627 [CQOI2009] 中位数
思路:1.将序列转化成01序列,将大于中位数的值设为1,小于中位数的值设为-1,中位数设为0。2.合法的子序列一定是包含0且何为0的一个连续子序列。然后只要用一些手段找到所有满足条件的[L,R]就行了。最原始的想法是O(n^2)的暴力枚举,居然能90分。下面附上代码片段: for (int i=1; i<=pos; i++) for (int j=pos; j<=n; j++) if ((j-i+1)&1 && sum[j]-sum[i-1]==0) a原创 2021-08-07 21:17:41 · 167 阅读 · 0 评论 -
[hdu多校] P7029 Median
题目链接首先要明确的是中位数必须在不同的集合中,只要能将剩下的数消去那么就是yes,否则是no。m个中位数把序列分成了m+1段,这m+1个集合中任意两个集合中的两个数都是可以两两消去的。那么这m+1个集合要满足什么性质才能让所有数都能消去呢?初步设想最后的情况有两种:1.所有集合都是空的2.有一个集合还有一些元素没被消去第一种情况是显然“yes”的。对于第二种情况容易证明最后还有元素没被消去的一定是包含元素最多的一个集合,要使它成立那么只能把剩下的元素放入包含比剩下的元素的最小值还要小的中位数的集原创 2021-08-06 22:50:04 · 167 阅读 · 0 评论 -
[hdu] P7025 Yes, Prime Minister
题本身不算难,但是容易错。队友wa了好几次,自己也没能幸免,所以要多模拟比赛提升coding的能力啊。下面是自己赛后整理的比赛时候的思维过程:#include<bits/stdc++.h>#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#define INF 0x3f3f3f3fusing namespace std;const int lim=3e7+5;const int maxn=7e7+5原创 2021-08-06 00:31:48 · 322 阅读 · 3 评论 -
[hdu多校]CCPC Strings
题目链接题目大意:在所有长度为n且只含有c,p的字符串集合中,计算含有不重复的字串ccpc的个数。思路:1.若允许重复,即“…ccpccpc…”的被算成两个ccpc。于是我们可以认为n-3个位置上的ccpc都对答案贡献1,可以得到共有(n−3)×2n−4(n-3)\times2^{n-4}(n−3)×2n−4个ccpc 。2.下面重点讲怎么去除重复。重复是因为出现了"ccpc/cpc", “ccpc/ccpc/cpc”…这样的字串,我发现对于一个无重叠的ccpc子串,在其后面加上cpc,他立刻就变成原创 2021-08-05 18:05:17 · 434 阅读 · 1 评论 -
[Luogu] P1122 最大子树和
直接d[x]+=max(0,dp[son]),但是答案不一定是dp[root],因为根节点不一定会被选上,要中途记录最大值。#include<bits/stdc++.h>#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#define INF 0x3f3f3f3ftypedef long long ll;const int maxn = 2e5+5;using namespace std;int n,r原创 2021-08-05 00:38:56 · 149 阅读 · 0 评论 -
[Luogu] P2014[CTSC1997] 选课
思路:(跟[Luogu] P2015 二叉苹果树几乎一模一样)1.建一棵有根树,因为每门课有一门或没有直接先修课,所以父亲是先修课2.树上dp,转移方程dp[x][j]=max{dp[x][k]+dp[son][j-k]}dp[x][j]表示在以x为跟的树上选j个点所能获得的最大值tips:由于父节点是先修课,所以在以x为跟的树上选j个结点,j>1时根节点必须选择,即dp[x][j]不能从dp[x][0]+dp[son][j]转移过来具体体现为下面的代码片段#include<bits原创 2021-08-04 23:53:19 · 189 阅读 · 0 评论 -
[Luogu] P1040[NOIP2003 提高组] 加分二叉树
思路:因为中序遍历已知,所以找到根以后就可以递归的处理问题了。定义dp[i][j]表示中序遍历i到j的子树的最大加分,那么dp[i][j]=max{dp(l,k-1)*dp(k+1,r)+dp[k][k]},然后可以记忆化搜索。#include<bits/stdc++.h>#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#define INF 0x3f3f3f3ftypedef long long ll;c原创 2021-08-04 22:51:31 · 153 阅读 · 0 评论 -
[Luogu] P2015 二叉苹果树
#include<bits/stdc++.h>#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#define INF 0x3f3f3f3ftypedef long long ll;const int maxn = 1e5+5;using namespace std;int n,q;int dp[1001][1001],w[maxn],size[maxn];int cnt,head[maxn];st原创 2021-08-04 18:44:02 · 157 阅读 · 0 评论 -
[Luogu] P5546 公共串
题意:求n个字符串的最长公共子串思路:后缀数组+二分1.若是求两个字符串的最长公共子串的长度且两字符串不太长本可以用dp2. 因为后缀数组方便处理子串问题,所以可以将问题转化成特殊的子串问题。所以将若干字符串拼成一个字符串s,并记录这个长串的每一部分属于哪个短的字符串。3. 但是这跟求子串的最长重叠长度不同,子串是“分组”的。所以将各个子串连接的时候要用“特殊”的连接符。4. 所求的不是具体的串而是长度,且这个公共串有单调性,即公共串越短越能满足条件,越长越不能满足条件。所以考虑二分答案。5.原创 2021-08-02 02:46:13 · 208 阅读 · 0 评论 -
[hdu多校] Lawn of the Dead
没看数据之前,第一想法是dp,复杂度O(mn)。看了数据后意识到这种想法是不行的,但是没关系可以借助dp的思想。能到达一个点,就到能到达他的左边或到达上面,进一步逐行考虑,就是要判断能否到达这个点的上面。如下图所示:这种思想还是很重要的,一行一行的看,从无序变有序类似的思想在P1985 [USACO07OPEN]翻转棋 Fliptile S中也有体现。标记的操作要用线段树完成,这边要开两个线段树,分别表示当前要处理的行和前一行。query操作表示查询要查询区间的子区间的最靠左的一个端点。#in原创 2021-07-30 15:59:23 · 266 阅读 · 0 评论 -
[hdu多校] Kanade Loves Maze Designing
本题就是要求一棵树上两节点之前权值的个数。曾经做过求序列上两点间区间的权值个数问题, 用的是“±1法”即在遍历的过程中ans++或者ans–。int cnt[maxn],ans=0;for (int i=l; i<=r; i++){ cnt[a[i]]++; if (cnt[a[i]]==1) ans++;}这样的方法在[Luogu]P1638逛画展结合“尺取法”出现过。如今要用在树上,只不过我们不能用for循环遍历,而应该用dfs遍历。还有就是不能确定两点求,应该选定根节点求与原创 2021-07-30 01:21:28 · 170 阅读 · 0 评论 -
[hdu多校] License Plate Recognition
图像识别题我采用dfs法,当然因为本题要求的特殊性更好的投影法比赛的时候一直在wa是因为我默认了汉字的长度是15思路:先求汉字最左端,正着扫描一边,然后处理其他连通块,倒着扫一遍。倒着扫的时候顺便求一下汉字的最右端#include<bits/stdc++.h>#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#define INF 0x3f3f3f3ftypedef long long ll;const原创 2021-07-29 19:17:53 · 126 阅读 · 0 评论 -
[hdu1506] Largest Rectangle in a Histogram
由于多校的时候一道单调栈的题没做出来,再来一题强化一下这个知识点吧#include<bits/stdc++.h>#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#define INF 0x3f3f3f3ftypedef long long ll;const int maxn = 1e5+5;using namespace std;int n;ll a[maxn];int l[maxn],r[max原创 2021-07-23 03:00:27 · 196 阅读 · 0 评论 -
[hdu多校] I love permutation
题目链接这道题的本质是求解一个序列中逆序对奇偶性的问题1.初见已知bn=a*n%p,可以先求出序列b,然后归并排序或是树状数组求逆序对,然而看了p的范围之后果断放弃(这尼玛哪能存的下啊 )2.进一步思考 (罚坐2小时之后看题解得)我们得到下面的信息:(1)如果在序列中ai,aj构成一对逆序对,那么(ai-aj)和(i-j)必定异号(2)题中要求的是序列逆序对的奇偶性,不必也不太可能求出具体的逆序对数整合信息后,研究逆序对的奇偶性可以转化为研究∏aj−aij−i\prod \frac{a_j-原创 2021-07-23 01:45:37 · 521 阅读 · 3 评论 -
[hdu多校] Maximal submatrix
单调栈+dp解决子矩阵问题,细节还是挺多的#include<bits/stdc++.h>using namespace std;const int maxn=2e3+20;int a[maxn][maxn];int up[maxn][maxn];int stk[maxn],top;int T;int main(){ scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&am原创 2021-07-21 12:50:08 · 157 阅读 · 0 评论 -
[Luogu]P4147 玉蟾宫
悬线法的应用一、方法介绍1.悬线是一条竖线,这条竖线要满足其上端点在矩形的上边界或其上端点的上面是障碍点(假设1是障碍)。2.我们枚举每个点的悬线,求出其最多能向左和向右扩展到何处,取最大值,就能求出最大子矩阵了。3.lft[i][j]: 表示(i,j)可以向左扩展的最大终点rig[][]: 表示(i,j)可以向右扩展的最大终点up[][]: 表示(i,j)最大向上不遇到障碍的长度二、回到本题#include<bits/stdc++.h>#define FAST ios::sy原创 2021-07-20 23:54:14 · 187 阅读 · 0 评论 -
[Luogu]P1638逛画展
注意到满足要求的区间具有单调性,于是想到用滑动窗口。区间具有单调性,即若[L,R]满足条件, [L,R+1]必满足条件,并且[R+1,L]有可能满足条件。如此一来不用O(n^2)枚举左右端点,这样去掉了许多根本不用考虑的情况#include<bits/stdc++.h>#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#define INF 0x3f3f3f3ftypedef long long ll;con原创 2021-07-19 16:40:23 · 209 阅读 · 0 评论 -
[hdu多校]Substring
本题是典型的“滑动窗口”题,所以借由本题复习一下“滑动窗口算法”。1.算法本质:贪心、利用之前的状态求解当前状态。2.适用条件:区间具有单调性,即若[L,R]满足条件, [L-1,R]必满足条件,并且[R,L+1]更有可能满足条件。3.可以解决的问题:找一个具有单调性的区间的最大值或者最小值。先上代码。#include<bits/stdc++.h>#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)#def原创 2021-07-19 15:13:09 · 152 阅读 · 0 评论 -
[hdu多校]Stacks
1.初见本来想用二维数组+暴力模拟,然而一看n最大可以到2e5, 时间复杂度O(n^2),遂放弃2.进一步联想记得之前在ccf的哪本教程上看到了一道类似的题,大概是用二维数组太大,可以改用邻接表,讲若干个一维数组组成的二维数组“压缩”。于是这题便可以用邻接表解决。3.关于邻接表我采用链式前向星的写法。int head[maxn],cnt;struct edge //边集数组{ int to; int next;}edge[maxn];void add(int from, int原创 2021-07-18 23:02:01 · 172 阅读 · 0 评论
分享