数据结构
文章平均质量分 70
Baoli1008
233
展开
-
AC自动机模版
//======================// HDU 2222// 求目标串中出现了几个模式串//====================#include #include #include #include #include using namespace std;struct Trie{ int next[500010][26],fail[500010]转载 2015-09-19 20:03:04 · 466 阅读 · 0 评论 -
UVa 11136 Hoax or what(multiset 应用)
multiset和set用法基本一样,区别是相同键值可以存在多个元素。代码:#include #include #include #include using namespace std;#include #define LL long longmultiset G;int main(){ int N; while(~scanf("%d",&N)){ if原创 2015-03-18 21:12:51 · 520 阅读 · 0 评论 -
UVa 11988 Broken Keyboard (a.k.a. Beiju Text) (模拟链表)
把原字符串从'[',']'处分隔成小字符串,然后维护每个字符串右边的字符串标号,已经第一个字符串head,最后一个字符串tail。读到一个'['表示把接下来的字符串放到最前面。']‘表示把下个字符串放到最后面,维护模拟指针即可。代码:#include #include #include #include using namespace std;#include s原创 2015-03-18 20:33:49 · 536 阅读 · 0 评论 -
UVa 11992 Fast Matrix Operations(两种标记的线段树)
本题涉及到了线段数大多数基本操作。因为只有20行,所以可以建20个线段树。线段树最重要的两个函数:pushdown 下移标记,并更新子节点数据。pushup 由2个子节点数据更新父节点数据。写法有很多,介绍一种不容易错的:保证在设置标记的同时更新节点信息。即:在update给某节点打标记,以及pushdown下发标记时,都马上更新节点信息。这样写的效果是pus原创 2015-03-14 19:20:49 · 465 阅读 · 0 评论 -
UVa 11235 Frequent Values(RMQ,ST算法)
注意到数列是非递减的,这代表相等的数字一定是挨在一起的。用a[i]表示数字i所在的段的长度。用left,right数组维护每个数字所在段左右边界位置。这样对于查询s~t,right[s]+1~left[t]-1这个子区间全都是完整的段,对这个子区间做RMQ,得到最长的段长度。然后再考虑这个子区间两个边界到s,t的距离。这两个距离也可能是答案。这三个答案的最大值就是最终答案。要特判s原创 2015-03-13 19:09:49 · 925 阅读 · 0 评论 -
UVa 11525 Permutation(二分+树状数组)
题中的展开实际就是康托展开。可以这样理解:假设确定了排列的第一位,那么还剩下K-1个数,全排列数为(K-1)!因此答案第一个数一定是S1+1以此类推,可以得知第i位的答案就是在未选的数中第Si小的。问题就转化成了如何确定未选的数中第k小的数是多少。用树状数组c,维护数i之前有多少个数被取走了。这属于单点修改,区间查询。这样如果i-c[i]>=k,那么i这个位原创 2015-03-21 12:13:30 · 561 阅读 · 0 评论 -
UVa 11991 I Can Guess The Data Structure(STL基础)
用stl中的3种数据结构依次去试,注意取之前要判断容器内是否是空的。代码:#include #include #include using namespace std;#include #include queue Q;stack S;priority_queue P;void init(){ while(!Q.empty()) Q.pop(); wh原创 2015-03-10 13:12:37 · 658 阅读 · 0 评论 -
UVa 11987 Almost Union-Find(带权并查集)
本题难点就是第二个操作。如果可以保证移动的节点一定是叶子节点,那就可以直接修改fa数组了。为了实现这点,可以开2×n个节点,初始时i的父节点是i+n,这样在合并时可以保证前n个节点一定一直都是叶子节点,问题就变成简单并查集了。代码:#include #include #include #include using namespace std;#define maxn原创 2015-03-20 10:49:14 · 581 阅读 · 0 评论 -
UVa 12299 RMQ with shifts(线段树单点修改 区间查询)
由于命令长度最大才30,shift操作包含位置的数量不超过12,可以视为常数。把每一个shift操作当成N个单点修改即可。对命令字符串解析,使用:for(int j=0;j if(isdigit(s[j])){ sscanf(&s[j],"%d",&pos[p++]); } while(isdigit(s[j])){ j++;原创 2015-03-20 12:10:20 · 581 阅读 · 0 评论 -
Codeforces Round #294 (Div. 2) D. A and B and Interesting Substrings(前缀和+map)
sum数组表示区间前缀和。如果位置i+1到位置j-1的和为零,那么sum[i]=sum[j-1],既sum[i]+a[k]=sum[j] (i和j位置字母为k)这样的话对每个字母枚举所有位置做起终点是可以的,但是时间复杂度为N^2。考虑用一个map维护前缀和中每个值出现的次数,这样可以用log时间查看某个值的前缀和存不存在。代码://// main.cpp//原创 2015-03-05 23:16:42 · 412 阅读 · 0 评论 -
Codeforces Round #295 (Div. 2) D.Cubes(STL SET应用)
STL中的SET是一个可以自动去重,排序的集合,底层为红黑树。遍历SET语法:set iterator p;for(p=S.begin();p!=S.end();p++){.....}删除元素 erase():参数即可以是key值也可以是迭代器地址。用两个Set数组Below和Top标记每个格子上面三格和下面三格分别有几个格子及序号。Rem也是一个Set,原创 2015-03-05 22:35:58 · 465 阅读 · 0 评论 -
uva 1428 Ping pong (树状数组)
题意:一条街道上有N个选手,他们要打乒乓球赛,每个人有一个z原创 2014-10-19 11:31:35 · 550 阅读 · 0 评论 -
uva 11997 K Smallest Sum(多路并归+优先队列)
题意:给出k个包含k个数的原创 2014-10-16 22:59:23 · 704 阅读 · 0 评论 -
poj 2104 K-th Number(线段树)
求区间第K大数。线段树每个区间维护一个有序的数组。原创 2014-10-10 18:52:14 · 750 阅读 · 0 评论 -
hdu 5073 Galaxy(数学+前缀和)
因为每次移动点最优一定是把这个点移动到zhuizhong原创 2014-10-31 10:04:03 · 381 阅读 · 0 评论 -
POJ 1056 IMMEDIATE DECODABILITY(字典树)
字典树的每个节点都标记是不是某个字符串的结尾字符。依次插入字符串,有两种错误情况:1.插入时经过了某个是结尾字符的节点2.到结尾字符时,对应的节点已经存在了代码://// main.cpp// 1056 IMMEDIATE DECODABILITY//// Created by Baoli1100 on 15/4/5.// Copyright (c)原创 2015-04-05 19:42:51 · 449 阅读 · 0 评论 -
HDU 3974 Assign the task (线段树)
修改一个点,实际上等价于同时修改一些点。而将一棵树深度遍历所得到的序列中,根节点相同的节点的标号刚好是相邻的。根据这个性质,用dfs对每个节点重新编号,修改一个点就变成了修改一个连续的区间。本题就变成了区间修改单点查询的线段树问题。代码:#include #include #include #include using namespace std;#include原创 2015-04-20 16:51:16 · 543 阅读 · 0 评论 -
Codeforces 570D Tree Requests(DFS重标号+树状数组)
能成为回文串的显然是数量为奇数的字母小于2个。问题转化成求范围内点中各种字母总个数。如果能构造出一个序列使同一原创 2015-08-20 08:22:02 · 551 阅读 · 0 评论 -
Codeforces 547B - Mike and Feet (单调栈)
res[x]表示长度为x区间的答案,那么如果i>j,res[i]对于每个元素需要找到左边和右边第一个大于这个元素的位置。单调栈可以在O(N)时间内找出所有元素的左右位置,思路就是维护一个数字单调递增的位置序列。具体看代码。代码:#include #include #include #include #define LL long long#include u原创 2015-08-04 09:34:18 · 811 阅读 · 0 评论 -
单调队列详解
转自Jason Damon点击打开链接 他的分析非常到位,顺便把单调队列给学了。很好,所以转了他的这篇文章。程序是我后来理解之后自己写的。看这个问题:An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the ver转载 2015-07-22 12:10:55 · 1598 阅读 · 0 评论 -
HDU 5289 Assignment (二分+RMQ) 2015多校训练一 1002
假设右端点r固定,那么如果能找到离得最远的一个l,使l到r满足要求,那么[l+1~r],[l+2~r].....都满足要求。所以可以枚举右端点,去找最远的满足条件的左端点,使满足条件,答案就是把这些长度求和。因为序列是静态的,所以可以用ST算法在log n时间求出任意区间内的最大,最小值,然后用这些值二分求解最远的l。代码:#include #include #includ原创 2015-07-22 11:19:13 · 449 阅读 · 0 评论 -
POJ 3250 Bad Hair Day(单调栈)
用一个栈来维护当前的递减序列,从左到右遍历,对于每个数cur,从栈顶开始把所有小于等于cur的数字都出栈,然后剩下的就都是可以看到cur的牛,并且保证了栈中的单调性。每次遍历对弹栈后的长度求和即可。代码:#include #include #include #include #include using namespace std;#define LL long lon原创 2015-07-22 12:09:50 · 428 阅读 · 0 评论 -
POJ 2823 Sliding Window(单调队列)
单调队列模板题。单调队列有两个性质:1.数值大小单调 2.队列元素位置单调插入查询的规则是,如果要求最小值,那么队列要从小到大排序,结果在队头。求最大值则相反。这是因为插入时要满足性质2,所以只能插在队尾,那么新元素要替换的值应该是比它大的,所以队列整体要从小到大排,才能保证大的数都在队尾一侧,实现查询最小值。插入时替换比它大的数的理由是,对于新的数,因为位置大于老的数,从原创 2015-07-22 13:28:14 · 431 阅读 · 0 评论 -
Codeforces 552E - Vanya and Brackets (中缀表达式求值)
左括号一定在*和+之间,右括号一定在+和+乘之间。乘号最多15个所以可以暴力枚举括号位置。#include #include #include #include #define LL long longusing namespace std;#define maxn 5005char s[maxn];int ps1[maxn];int ps2[maxn];LL原创 2015-08-10 12:53:05 · 430 阅读 · 0 评论 -
中缀表达式求值
转自:点击打开链接 海子 中缀表达式求值问题 中缀表达式的求值问题是一个比较常见的问题之一,我们通常在编写程序时,直接写出表达式让编译器去处理,很少去关心编译器是怎么对表达式进行求值的,今天我们来一起了解一下其中具体的原理和过程。 表达式一般来说有三种:前缀表达式、中缀表达式、后缀表达式,其中后缀表达式又叫做逆波兰表达式。中缀表达式是最符合人们思维转载 2015-08-07 16:35:19 · 4610 阅读 · 1 评论 -
Codeforces 555C. Case of Chocolate (SET应用)
对于U的操作,能到达的y的上界和x值大于它最接近的操作的y的上界是一样的:1.如果是L的操作,上界就是那个L操作的y值。2.如果是U的操作,上界就是这次U操作所能到达的上界。对于L的操作,则是找y值大于它最近的操作。所以建立两个map U,L,一个key值是x,一个是y,因为map的lower_bound是按照key值查找的。对于U操作,结束后U要插入pair(原创 2015-07-28 10:17:27 · 644 阅读 · 0 评论 -
Codeforces 558D - Guess Your Way Out! II (求区间交,并)
题中给出的每一个区间都可以转化为叶子那层的一个区间,所以步骤就是:1.对于所有ans=1的区间求区间交,方法很简单就是两个l取最大值,r取最小值,最后答案一定在这里面。2.对于ans=0的区间,求区间并的补集。方法是用一个pair,对每个区间的左端点附加信息-1,右端点附加信息1,排序后从左往右扫,累加这个附加信息,当累加和等于0时,说明在该点前的所有区间都结束了,那么从这个点到下一个区间原创 2015-07-26 11:29:07 · 646 阅读 · 0 评论 -
557C - Arthur and Table (前缀和)
如果选择L为最后的最长长度,那么大于L的桌腿必须全去除。然后假如此时剩下M条桌腿,长度L的桌腿有num[L]条,如果tmp=num[L]*2-1-M0,就需要在小于L的腿中选择tmp条花费最小的桌腿。首先把桌腿按长度排序然后预处理前缀和,这样后可以O(1)得到大于L的桌腿的总代价。然后因为代价的最大值才200,那么维护小于L的每种代价桌腿的数量,按照计数排序的方法选择桌腿去除,再维原创 2015-07-26 13:35:22 · 918 阅读 · 0 评论 -
POJ 1195 Mobile phones (二维树状数组)
模板题注意:1.树状数组下标要从一开始,不然会死循环2.树状数组修改循环要到S而不是S-1代码:#include #include #include using namespace std;#define LL long longLL c[1050][1050];int N;int lowbit(int n){ return n&(-n);}vo原创 2015-05-07 20:31:16 · 366 阅读 · 0 评论 -
POJ 1151 Atlantis (线段树+扫描线 求矩形面积并)
经典扫描线题,算法网上有很详细的,这里简单说一下:把每个矩形拆成两条竖边,标记每条边是左边的还是右边的,把所有的边按x坐标排序。用一个数组cov标记整个y轴每个部分在多少个矩形中,哪些不是。把浮点数离散化。然后开始扫描:先把答案加上(全部在矩形中的区间的长度和)×(这条边x坐标和前一条边x坐标之差),代表这两条边之间被覆盖的面积,然后这条边如果是左边,就把所覆盖区间的cov数组+1,是右边原创 2015-05-14 20:08:31 · 790 阅读 · 0 评论 -
HDU 4747 Mex (线段树)
本题关键是想到如何转换成区间求和操作。用mex[i]表示第1到第i个数这个区间的mex值,这样对mex[1]~mex[N]求和,就是所有包含第一个数的区间的mex值和。包含第一个数的都求完了,可以把第一个删掉。这样mex[i]就变成了第2到第i个数这区间的mex值,同样对2到N这个区间的mex[i]求和,然后一直一个一个删除到最后一个。删除a[i]会影响哪些区间:假设i位置原创 2015-05-02 10:05:13 · 685 阅读 · 1 评论 -
csu 1335 高桥和低桥(树状数组+二分)
输入所有桥的高度后先对桥排序,然后先求出原创 2014-10-10 18:50:20 · 852 阅读 · 0 评论 -
hdu 4122 Alice's mooncake shop(线段树RMQ)
对于一个时间t,在i时刻(i>=t-T)zuo原创 2014-11-11 14:53:06 · 419 阅读 · 0 评论 -
hdu 1213 HOW MANY TABLES
题目链接:点击打开链接原创 2014-08-14 11:17:51 · 345 阅读 · 0 评论 -
hdu 1698 Just A Hook
题目链接:点击打开链接线段树quj原创 2014-08-13 13:16:29 · 448 阅读 · 0 评论 -
acdream(18) Disappeared Block(离散化+二分)
题目链接:点击打开链接原创 2014-09-09 22:17:04 · 504 阅读 · 0 评论 -
POJ 2886 Who Gets the Most Candies?
题意:输入N,K,表示N个小朋友围成一个圈,每个xioa原创 2014-08-11 22:26:33 · 385 阅读 · 0 评论 -
poj 2828 Buy Tickets
题目链接:点击打开链接题意:插队,原创 2014-08-11 14:42:08 · 357 阅读 · 0 评论 -
hdu 1754 I Hate It (树状数组版)
题目链接:点击打开链接解释一下三个函数:add:先将原数组中原创 2014-08-09 16:09:40 · 633 阅读 · 0 评论 -
hdu 1394 Mininum Inversion Number(线段树版)
题目链接:点击打开链接先用原创 2014-08-09 21:51:41 · 370 阅读 · 0 评论