数据结构
文章平均质量分 73
wwwiskey
学生
展开
-
HDU 4288 Coder 【线段树+离线处理+离散化】
题意略。离线处理,离散化。然后就是简单的线段树了。需要根据mod 5的值来维护。具体看代码了。/* 线段树+离散化+离线处理*/#include #include #include #include using namespace std;typedef long long ll;#define N 100010ll sum[N<<2][5];int a[原创 2013-10-06 13:36:19 · 1792 阅读 · 0 评论 -
CF 258E Little Elephant and Tree 【线段树,树上DFS序列】
题意:对一颗树进行m次操作,每次操作(a,b)都是在节点a和b的子树的所有节点后边加入操作的序号。最后询问每个节点分别与多少个其他节点拥有相同的操作编号。英文题解:http://codeforces.com/blog/entry/6213首先根据DFS顺序将树转化为一个线段树,剩下的问题就可以用线段树来解决了。如果节点x进行了第i种操作,那么x所有的儿子节点也都进行了相同的操作,只需要原创 2013-07-30 02:18:25 · 1968 阅读 · 0 评论 -
POJ 3691 DNA repair【AC自动机+DP】
只能说这道题目的数据好强啊,以前写的自动机都是有缺陷的但是可以过题,这次被坑大发了……呜呜f(i, j)表示长度为i的串,到j状态时需要更改的次数。f(i, u) = min(f(i, u), f(i-1, j) + (s[i] != k))u是状态j的子状态。#include #include #include #include using namespace原创 2013-08-13 17:07:50 · 1066 阅读 · 0 评论 -
POJ 2778 DNA Sequence【AC自动机+矩阵快速幂】
#include #include #include #include #include #include using namespace std;typedef long long ll;struct AC_Automata { #define Nn 102 #define M 4 int ch[Nn][M], val[Nn], f[Nn], last[原创 2013-08-10 21:36:32 · 2995 阅读 · 2 评论 -
HDU 4661 Message Passing 【Tree】
题意:给一棵树,每一个结点都有一个信息,每一个时刻,某一对相邻的结点之间可以传递信息,那么存在一个最少的时间,使得所有的节点都可以拥有所有的信息。但是,题目不是求最短时间,而是求最短时间的情况下,有多少种传递方式:某一时刻传递信息的双方不一样则认为是不同的传递方式。(表述的不是很清楚,自己看原题了)容易的出,最短的时间内,当然是每个节点将自己的信息想外传出去一次,并且接受一次信息,原创 2013-08-09 19:45:15 · 1854 阅读 · 0 评论 -
TC SRM 570 div2 1000【Tree,树上统计】
将一棵树上的所有结点分成两个集合(其中一个集合可以为空),但是“人类”的集合必须是联通的。问总共有多少种分法。将整棵树确定一个根,那么每个结点被选择之后,其父节点不被选择(此节点是个分界)的方案数=(所有儿子的方案数+1)的乘积。(+1表示当前子树的所有儿子都不选择)最后将所有结点作为分界的结果累加起来即可,然后+1(所有结点都不被选择)const int N = 55;c原创 2013-08-20 20:29:33 · 1176 阅读 · 0 评论 -
CF 294E Shaass the Great【Tree】
将树的一条边移掉,然后将这条边重新连接两棵子树,使新树:两两点对的距离之和最小。枚举删掉的边,对每种情况都计算一下,然后取最小值。对于每种情况,假设左子树的两两点对和为S1,右子树为S2,子树结点个数分别为C1,C2,两个子树到树根的距离和分别为R1,R2,当前枚举的边的权值为w,则整棵树的代价为:两棵子树的点对和+经过当前边的点对和S1 + S2 + (C1 + C2)*w +原创 2013-08-19 22:19:59 · 1272 阅读 · 0 评论 -
HDU 2896 病毒侵袭 【AC自动机】
HDU 2222 仅仅求出了和文本串匹配的模式串个数,本题要求求出匹配的模式串的编号。不同的部分在代码中的注释部分。#include #include #include #include #include #define MAX_NODE 60005#define MAX_CHILD 130using namespace std;vector ans;class原创 2013-08-06 11:55:12 · 1264 阅读 · 0 评论 -
HDU 3065 病毒侵袭持续中
询问每个模式串在文本传中出现的次数。文本串中出现的字符不一定都是大写字母,只需要在匹配的时候,对文本串进行特殊处理,将连续的大写字母段当成合法的一个文本串即可。然后……就是简单的统计了。#include #include #include #include #include #include using namespace std;int原创 2013-08-07 16:42:50 · 936 阅读 · 0 评论 -
HDU 4666 Hyperspace【最远曼哈顿距离+优先队列】
这个题是动态的求最远曼哈顿距离。做法和POJ 2926 Requirements一样,都是通过二进制枚举符号的情况。每插入一个节点都要询问最大值和最小值,因此用一个优先队列或者堆维护就可以了。#include #include #include #include #include using namespace std;#define N 60010#define i原创 2013-08-14 08:56:40 · 1889 阅读 · 0 评论 -
SGU 134 Centroid【树的重心】
树的重心。递归求解即可。#include #include #include #include using namespace std;#define N 16100vector g[N];int n, cur, s[N], f[N];void getroot(int now, int fa) { s[now] = 1; f[now] = 0; int原创 2013-08-14 11:01:21 · 1135 阅读 · 0 评论 -
POJ 1655 Balancing Act【树的重心】
这个题也很裸了……不多说。#include #include #include #include using namespace std;#define N 20010int s[N], f[N], n, root;vector g[N];void getroot(int now, int fa) { int u; s[now] = 1; f[now]原创 2013-08-14 14:54:34 · 1293 阅读 · 0 评论 -
HDU Ads Proposal 【树状数组】
题意:N个customer,M个advertisement,每个ad只属于一个cus,每个ad都有一个点击量和一个长度值。现在对于每个询问,求出所有cus的前k大点击量的广告的总长度。对于每个ad,求出他在所属的cus里面的排名,这个一边排序就可以了。将长度累加到对应排名上面。树状数组维护查询就可以了。#include #include #include us原创 2013-10-04 19:51:39 · 1399 阅读 · 0 评论 -
HDU 4000 Fruit Ninja 【树状数组】
题意:给1-N的一个排列,找出所有的(x, y, z) 使得x 题解:对于每个x,只需要找到比x靠后,而且比x大的数的个数,这样的组合数为:n*(n-1)/2这里面有重复的情况:i 树状数组统计x之前出现的比x小的个数,剩下的就全部可以算出来了。#include #include #include #include using namespace std原创 2013-10-04 18:15:14 · 1314 阅读 · 0 评论 -
BZOJ 2599 [IOI2011]Race【Tree,点分治】
给出N(1 点分治,这道题目和POJ 2114很接近,2114是求是否存在长度为K的边,但是那个K比较大。但是这道题目的K比之小了10倍。1. 用V[i]表示到当前树根root的路径长度为i 时的点(赋值为root结点即可),这样就可以用来判断两条到根的路径长度之和是否等于K: 结点a的root的距离为i,结点b到root的距离为j,处理完a之后会得到V[i] = root,那么原创 2013-08-16 17:09:29 · 3682 阅读 · 0 评论 -
HDU 4679 Terrorist’s destroy【Tree】
给一棵树,每条边上都有一个权值,去掉树上任意一条边之后,分成两个子树,两个子树的最长路与这条边上的权值相乘,的到一个乘积。问去掉那一条边可以使这个乘积最小。首先找到树上的最长路,那么删边的时候有两种情况:1. 这条边是最长路上的边2. 这条边不是最长路上的边对于第一种情况,很容易计算出乘积。对于第二种情况,只需要计算出被分成的两个子树里面的最长路径长度即可,这个可以预处理一下。原创 2013-08-15 19:23:47 · 2139 阅读 · 2 评论 -
POJ 2114 Boatherds【Tree,点分治】
求一棵树上是否存在路径长度为K的点对。POJ 1714求得是路径权值刚开始我以为只要在分治过程中出现过长度为K的就算是找到了,其实不然,因为可能是相同子树里面的两个结点,这个结果显然是错误的。#include #include #include #include using namespace std;struct node { int v, l; node(原创 2013-08-16 14:53:17 · 4142 阅读 · 1 评论 -
HDU 4676 Sum Of Gcd【数论,数据结构(分块)】
静态区间查询,没有更新操作,瞬间就想起来了哪个O(n*sqrt(n))的做法。关键是区间转移的时候不会处理了,只能说数学拙计了……对于此类问题的时间复杂度分析,详见:http://blog.csdn.net/yang_7_46/article/details/9618637买一送一,以一场多校的题目是题解给的是树状数组,其实也可以用这个算法水过,时间也挺快。http://blog.cs原创 2013-08-15 21:10:56 · 3016 阅读 · 1 评论 -
POJ 1987 Distance Statistics【Tree,点分治】
这道题目和POJ 1741基本一样了。树上的分治。此类算法参考论文:09年国家集训队论文《分治算法在树的路径问题中的应用——漆子超》#include #include #include #include using namespace std;#define N 40005struct node { int v, l; node() {};原创 2013-08-14 20:22:52 · 1976 阅读 · 0 评论 -
POJ 1741 Tree【Tree,点分治】
树上的算法真的很有意思……哈哈。给一棵边带权树,问两点之间的距离小于等于K的点对有多少个。将无根树转化成有根树进行观察。满足条件的点对有两种情况:两个点的路径横跨树根,两个点位于同一颗子树中。如果我们已经知道了此时所有点到根的距离a[i],a[x] + a[y] 在进行分治时,为了避免树退化成一条链而导致时间复杂度变为O(N^2),每次都找树的重心,这样,所有的子树规模就会变的很小原创 2013-08-14 16:27:47 · 17542 阅读 · 4 评论 -
CF 256E Lucky Arrarys 【线段树+DP】
规定Lucky Array中任意相邻的两个数(ai, ai + 1)在w数组中为1。数组初始为0,问有多少种排列方式使数组是Lucky的。并且每次更新之后都要给出总的方案数。动态规划可以求相邻两个区间合并之后的结果f(i, j)表示当前区间以i开头,以j结尾的总方案数。那么配合更新操作,我们就可以用线段树来维护。树中每个节点上面都有一个f数组记录当前区间的方案数。对于每次更新后的询原创 2013-08-05 10:07:43 · 1096 阅读 · 0 评论 -
CF 86D Powerful array 【分块算法,n*sqrt(n)】
给定一个数列:A1, A2,……,An,定义Ks为区间(l,r)中s出现的次数。t个查询,每个查询l,r,对区间内所有a[i],求sigma(K^2*a[i])离线+分块将n个数分成sqrt(n)块。对所有询问进行排序,排序标准: 1. Q[i].left /block_size 2. 如果1相同,则 Q[i].right 问题求解原创 2013-07-29 17:51:54 · 3301 阅读 · 4 评论 -
POJ 1703 Find them, Catch them
并查集应用。这个题目和【食物链】类似。 a[x] = 0 表示x与父节点同gang a[x] = 1 表示与父节点不同gang#include #include using namespace std;const int MAXN = 100005;int set[MAXN], a[MAXN];int Find_set(int x) {原创 2013-01-29 21:02:24 · 2542 阅读 · 7 评论 -
POJ 1988 Cube Stacking
并查集应用。题意:初始有N个stack,编号为1-N,给两个操作M x y :将x所在stack的所有cube移到y所在stack的上面C x :统计在x下面的cube的个数题解:fa[x]表示x的父节点,num[x]表示以x为根的并查集中节点的总数,rank[x]表示x在当前stack(并查集)中的排名那么,在x下面的cube个数为: num[father(原创 2013-01-28 16:35:41 · 737 阅读 · 0 评论 -
POJ 1182 食物链
并查集的应用。题意略。题解:用数组a来表示x节点与父节点的关系,Union操作和Find操作看代码。 a[x] = 0 父子同类 a[x] = 1 子吃父 a[x] = 2 父吃子#include #include using namespace std;const int MAXN = 50005;int set[MAXN], a[M原创 2013-01-29 17:45:44 · 855 阅读 · 0 评论 -
LCA && RMQ
讲解详见:http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor题目……原创 2013-01-26 23:45:15 · 744 阅读 · 0 评论 -
POJ 1769 Minimizing maximizer
DP+线段树。(这道题目整的挺纠结,有待琢磨……)题解(转载的):题意分析: 如果我们考虑将数组看成一条[1, n]的线段, 而每项操作也看成是从[ i[k], j[k] ]的线段, 那么题意就是按照线段的输入顺序, 将线段[1, n]从左到右依次覆盖, 问题变成求最小的覆盖线段总数.算法思想: 考虑最基本的规划方法, 用Opt[原创 2013-01-26 23:16:44 · 3122 阅读 · 0 评论 -
POJ 1470 Closest Common Ancestors
最近公共祖先:在线算法和离线算法。离线算法(Tarjan):伪代码如下:注意: 存储树的时候存储的是单向边,所以checked[u] = true 写在中间不会出现死循环, 这样可以避免重复计算公共祖先。如果存储的树是双向边的话,就必须写在前面,这样子可以避免死循环,双向边的情况如下但是这道问题确实统计公共祖先的次数的,因此如原创 2013-01-25 19:20:03 · 1279 阅读 · 0 评论 -
POJ 1986 Distance Queries
题意:给一棵树的信息。给q个询问:farm A和farm B,输出A和B的距离。最近公共祖先,但是要记录距离的信息。#include #include #include #include #include using namespace std;const int MAXN = 40004;typedef pair PAIR;vector edge[MAXN], que原创 2013-01-27 20:46:13 · 1504 阅读 · 0 评论 -
树状数组
//树状数组的模板const int LEN = 1000;int c[LEN];int n; //数组的长度 int lowbit(int x) { return x & (-x);}void add(int index, int num) { while (index <= n) { c[index] += num; index +=原创 2012-08-01 10:49:45 · 508 阅读 · 0 评论 -
划分树
划分树详解,参见论文 《划分树算法总结》论文里面有些代码不是很完美,所以建议参照我的代码,不过里面讲的还是蛮清楚的。里面的三道题目这里面只给出两道题目的代码(论文题目的题号有误,注意)。POJ 2104 k-th number裸的划分树,求区间第k大数#include #include #include using namespace std;co原创 2013-02-26 14:03:59 · 1735 阅读 · 0 评论 -
ZOJ 3230 Solving the Problems
优先队列。按a和b为关键字分别建立优先队列即可。#include #include #include using namespace std;struct node1 { int a, b; node1() {} node1(int _a, int _b): a(_a), b(_b) {} bool operator < (const node1 &原创 2013-05-06 17:41:36 · 1077 阅读 · 0 评论 -
POJ 2513 Colored Sticks 【Trie树】
Trie树+欧拉路径的判定。并查集来判断连通性,然后判断欧拉路径的条件就可以了。Trie树的插入操作和查询Index操作,其他操作没有写。没有写全的模板。#include #include using namespace std;#define N 500002struct node { int num; bool is_word原创 2013-05-24 20:47:52 · 1264 阅读 · 0 评论 -
CF 13E Holes 【块状链表】
题目描述:一条直线上n个点,每个点有个“弹力”,可以把当前位置x上面的ball弹到x+a[x]上面。两种操作0. 修改a处的弹力值,编程b1. 询问a点的ball经过多少次能跳出n个点外(就是出界了)。。。。求出弹跳的次数和最后落脚的点。块状链表就是用来暴力模拟的。用块状链表可以把时间复杂度从O(n)变成O(sqrt(n))。这道题目的复杂度为O(m*s原创 2013-07-29 19:56:31 · 1571 阅读 · 0 评论 -
HDU 4638 Group 【树状数组,分块乱搞(莫队算法?)】
根据题目意思,很容易得出,一个区间里面连续的段数即为最少的group数。题解上面给的是用树状数组维护的。询问一个区间的时候,可以一个一个的向里面添加,只需要判断a[i]-1 和 a[i]+1是否已经添加在内,如果两个都在,则总段数减1,如果两个都不在,总段数加1,其他情况总段数不变了。这里有一个需要深入理解的就是其实无论是按顺序添加还是随便添加,统计结果是不变的,但是要看怎么维护了。每原创 2013-08-03 19:39:29 · 2926 阅读 · 0 评论 -
CF 242E XOR on Segment 【线段树】
两种操作:1、求区间和2、对区间上的每一个数进行异或(xor)运算直接维护区间和的话区间更新无法进行,所以,要维护的信息是区间内按位和(即每个二进制位出现的次数),那么进行xor运算的时候,只需要进行0 和 1的转换就可以了。这样的话,就是一个基本线段树+延迟操作+维护各个二进制位信息。#include #include using namespace st原创 2013-08-03 10:04:35 · 1678 阅读 · 0 评论 -
CF 319B Psychos in a Line 【单调队列】
维护一个单调下降的队列。对于每一个人,只需要找到在他前面且离他最近的可以杀掉他的人即可。#include #include #include #include using namespace std;#define N 100005vector v;int f[N], n, t, cnt;int main() { scanf("%d", &n);原创 2013-08-03 11:42:39 · 1551 阅读 · 0 评论 -
CF 121E Lucky Array 【树状数组】
这个题目的数据感觉不能更水了。从复杂度上计算,肯定有极限数据可以卡掉暴力方法的么。总之,暴力的做法就是树状数组了,对于区间更新,就挨个更新就是了。当然,判断是否是Lucky Number的话,可以用一个数组标记一下,因为题目中有说数据不会超过10000的。总之就是一个非常不靠谱的方法过了……话说用线段树的区间操作以及延迟标记的话,真心不知道怎么判断加上d之后的Lucky Number的个数,o原创 2013-08-02 19:47:22 · 1326 阅读 · 0 评论 -
POJ 1785 Binary Search Heap Construction 【笛卡尔树构造,线段树RMQ(Range Max/Min Query)】
题目注意: 两个要求,1. 第一关键字满足搜索序,2. 第二关键字满足堆的性质。这道题目的标准(简单)解法:笛卡尔树。但是还有: 分治+RMQ, 其中,RMQ问题有两种方法:线段树和Sparse Table算法。笛卡尔树定义:笛卡尔树是一棵二叉树,树的每个节点有两个值,一个为key,一个为value。光看key的话,笛卡尔树是一棵二叉搜索树,每个节点的左子树的key都比原创 2013-01-24 20:24:40 · 3790 阅读 · 6 评论 -
POJ 2201 Cartesian Tree 【笛卡尔树】
构造笛卡尔树。我用的是 排序+左旋 的方式,这种方式并不是最好的构造方式,先写出来再说,今天不行了,改天在学习其他的算法。构树技巧:增加一个虚拟的根节点,根节点的value优先级最高,可以保证此节点一直是根节点。这道题目的数据有点……,所以不需要判断不合法的,所有的数据都可以构成笛卡尔树,所以判断NO的就可以省了。。。。⊙﹏⊙b汗排序+左旋:#inc原创 2013-01-25 00:41:58 · 1373 阅读 · 0 评论