随笔分类 - 算法--数据结构
摘要:题目源自 XTUhttp://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1170Coins题意: 有编号为1到10^9个盒子,每个盒子为空或装部分球,现在给K个区间,形如[ L, R , num ] 表示编号为 L到R的盒子中至少有num个球,求所有盒子装球的最小数量和。线段树解法 其实不难想到解法,我们依据c的值从小到大覆盖指定区间,若出现当前区间被完整覆盖时,则意味着冲突,应该为 "Error",否则求和。重要的是如何实现,区间覆盖问题,是线段树(segment Tree)的强项。 我们且先,假定盒子数量
阅读全文
摘要:题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1208题意: 中文题就不说了,都能看明白解法: 数据结构题,应该使用一个BST类型的数据结构来实现,bst,treap,avl,splay,sbt,等等都可以。 我的解法是维护两个 spaly tree,A表示宠物,B表示收养者, 对于 a = 0, 添加宠物时, 首先检查 B是否为空, 若执行 A.insert( a ), 否则,调用方法 B.deal( a ). deal( val ) 的思路: 若B中原本就有val值,则花费为0,直接删除key[x]=val的节点。 否则插...
阅读全文
摘要:写写思路吧,WA了数十次,都快哭了...改这改那的- -...A了以后都不知道先前哪里写搓了...设定一个阀值sqrt(M),当顶点关联的边数量超过阀值,则令其为超级点,否则为普通点,若边数量为M,则超级点数量不超过2*sqrt(M),证明如下: 因为,无向图中,假定有2*sqrt(M)个顶点相关联的边至少为sqrt(M),则边数量为, 2*sqrt(M)*sqrt(M)/2 = M, 则意味着边数量大于M,所以矛盾, 得证.我们设定一个数组 ans[3],来表示所求结果, 对于每个顶点添加一个sum[2],代表与其关联的顶点颜色为 0/1的边权和.假定我们修改一个顶点x 的颜色, 若其颜色.
阅读全文
摘要:Splay 的属性 1 struct Splay{2 int rt, cnt;3 int ch[N][2], pre[N], sz[N];4 LL sum[N], add[N], val[N];5 }Splay 的操作主要集中在 1. Rotate( x, d ) 旋转分为 左旋(d=0), 右旋(d=1) 2. Splay( x, goal ) 将节点x 旋转到 节点goal下 3. Rotate_To( k, goal ) 将左数第k个节点旋转到 节点goal 下 1 void rotate(int x,int d){ 2 int y = ...
阅读全文
摘要:题意 N个数,M个操作,操作有三类: 1. D,A,B,C 区间[a,b]中 大于0 的数 除以C,计算机整除 2. M,A,B,C 区间[a,b]所有数减去C 3. S,A,B 区间[a,b]求和解法 区间更新和求和,线段树上延迟更新就可以了。主要是除法如何维护。 这里的数C <= 5*1E5 , 因为大于0才除,所以每个数最多被除 log(Ai) 次, N个数则最多被除 N*log(Ai) 次了。 所以做除法可以直接更新到底,还有就是使用一个标记,区间中都不可被除时,就没必要更新到底了。 另外,除数是1的时候,不能除,貌似后台数据好多1,╮(╯▽╰)╭~~~ Vi...
阅读全文
摘要:题意 n(n<=2e4)个顶点m(m<=6e4)条边,每个顶点有个权值val_i, 然后有Q(Q<=5e5)次操作. 操作分为三类: D x : 删除第x条边 Q x k : 查询与节点x关联的所有顶点中第k大 C x V : 将节点x的权值更改为V 输出查询的均值 /sum { Query_val } / Query_num解题思路 离线算法 对于删除,可以通过将所有操作读入后,从后往前处理。把删除边转换成插入边。 对于查询第k大顶点,我们可以使用 treap维护的名次树 kth来实现 对于修改操作,我们先将原来的值删除,然后再插入新值。 因为我们使用离线逆向...
阅读全文
摘要:Treap是一颗拥有键值,优先级两种权值的树. 对于键值而言,这棵树是排序二叉树(BST Balance Sort Tree); 对于优先级而言,这棵树是堆,既在这棵树的任意子树中,根节点的优先级是最大的(这个性质称为堆性质) 1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<algorithm> 5 using namespace std; 6 struct Node{ 7 Node *ch[2]; //左右子树 8 int r; // 优先级,数值越大,
阅读全文
摘要:题意 N个人,每个人有一个属性(x,y), 若对于一个人P(x,y),不存在P`(x`,y`)使 x`< x , y` <= y or x` <= x , y` < y , 则认为 P是有优势的.问逐一的输入N个人信息,在当前情况下有优势的人的数量.解题思路 若添加当前人信息进入, P(x,y), 其可能有两种情况: 1. 若 存在 P`(x`,y`), 使得 x`<x,y`<=y or x`<=x,y`<y, 则P无优势,则不必加入. 2. 若其不存在则其 有优势,并会导致部分点失去优势,将那些点删除. 这里 通过 <x,y> 进行
阅读全文
摘要:Splay 概念文章:http://blog.csdn.net/naivebaby/article/details/1357734叉姐 数组实现:https://github.com/ftiasch/mithril/blob/master/2012-10-24/I.cpp#L43Vani 指针实现:https://github.com/Azure-Vani/acm-icpc/blob/master/spoj/SEQ2.cpphdu 1890 写法:http://blog.csdn.net/fp_hzq/article/details/8087431HH splay写法:http://www.n
阅读全文
摘要:一, Sequence SearchView Code // Sequence_Search// yefeng1627#include<stdio.h> #include<stdlib.h>#define True 1#define False 0#define MaxLength 100typedef int KeyType;typedef int DataType;typedef struct{ KeyType key; //关键字域 DataType other; //其它属性域 }ElemType;typedef struct{ ElemType...
阅读全文
摘要:前言:关于区间最值问题的求解,我们一般采用线段树来维护区间最值,得到了O(NlogN)的算法。但对于区间第k值问题,我们应该如何解决呢?本文将介绍一种基于线段树思想衍生出来的新结构——划分树,来解决这个问题。1 划分树其实,划分树和线段树的区别并不大,可以归纳为两点: 1.1 划分树每一个区间[L,R]维护的是一个一维数组[L..R]。 1.2 划分树每一个根结点[L,R]中前[(R-L+1)/2]小的点组成左子树,后[(R-L+1)/2]大的点组成右子树。2 划分树求区间k值 我们首先修改一下思考方式,原问题变成在已经sorted的数列中找出第k个在区间[s,t]中的数字。 先给出一...
阅读全文
摘要:题目大意 链接http://acm.hdu.edu.cn/showproblem.php?pid=3397 在一个由N个0或1构成的序列上进行五种操作: 0 a b : 将区间[a,b]序列置为0 1 a b : 将区间[a,b]序列置为1 2 a b: 将区间[a,b]序列0,1互换 3 a b: 输出区间[a,b] 为1的数量和 4 a b: 输出区间[a,b] 连续1的最大长度解题思路 分析题目的5种操作, 对于 0, 1, 3 操作,可以理解为区间覆盖,然后区间求和。这个对于普通的线段树是很好做的。 对于 2,4 操作, 涉及到区间的旋转,以及子区间...
阅读全文
摘要:题目题意异常恶心,难以理解...... 呵呵.....不过题意是 Lyush大神 花费一小时看明白后透露给笔者的, 到现在依然YM此大婶当中...... 先说说题目大意: 一颗完全二叉树,有 N ( n <= 1024,且必定为2的整数幂,意味着是一颗完全二叉树 ) 个叶子节点,每一个节点都含有一个长度为 LL ( L <= 1000 ) 的串 ( 串仅由大写字母构成), 现仅仅知道N个叶子节点串的组成.其他节点串不知道. 但我们知道,直接父节点相同的两个子节点,其对应位置不同则花费为1. 整棵树花费最小. 让你求,整棵树的最小花费, 以及根节点的可能串元素...
阅读全文
摘要:定义结构体 struct Dir { vector< Dir > dir; vector< string > file; }; 通过递归处理, 和输出 就很方便了。 要注意,当出现子目录时,递归下去处理,回朔后再将其加入到父目录的vector中,不然没有保存到之后的信息。解题代码:View Code #include<algorithm>#include<iostream>#include<vector>#include<string>#include<stdio.h>using namespace std;s
阅读全文
摘要:题目大意 一颗含有N个顶点的树,节点间有权值, 节点分为黑点和白点.问题是 找一条黑点数量不超过K个的最大路径.解题思路: 因为路径只有 过根节点以及不过根节点, 所以我们可以通过找寻树重心分治下去. 问题就退化成了处理: 对于当前以 x 为根的树, 其最大路径 对于X的所有直接子节点, 定义函数 G( I, J ) 表示子节点 I为根的树不超过J个黑点的最大路径. 定义函数 dep( i ) 表示以 i为根的树,最多黑点数量. 则结果为 ans = MAX{ G(u,L1) + G(v,L2) } ( u != v, 且 L1+L2 <= K - (当前根节点...
阅读全文
摘要:前言:关于区间最值问题的求解,我们一般采用线段树来维护区间最值,得到了O(NlogN)的算法。但对于区间第k值问题,我们应该如何解决呢?本文将介绍一种基于线段树思想衍生出来的新结构——划分树,来解决这个问题。1 划分树 其实,划分树和线段树的区别并不大,可以归纳为两点: 1.1 划分树每一个区间[L,R]维护的是一个一维数组[L..R]。 1.2 划分树每一个根结点[L,R]中前[(R-L+1)/2]小的点组成左子树,后[(R-L+1)/2]大的点组成右子树。2 划分树求区间k值 我们首先修改一下思考方式,原问题变成在已经sorted的数列中找出第k个在区间[s,t]中的数字。 先给...
阅读全文
摘要:维基百科介绍:http://en.wikipedia.org/wiki/Kdtree KD树是一种能在 O(N)时间内把平面划分成若干个区域,然后在均摊 O(logN)的时间内找到某个区域内所有点的数据结构。其思想是,每次把当前处理的区域按照点数分成两部分,然后对两部分进行递归处理。。。分成两部分有两种策略: 一种是横着竖着横着竖着交替划分。。 一种是把坐标跨度大的那一维划分成两部分。似乎没什么影响。上图是一种可行的划分方式。每次找到当前处理点集中的中点,以这个中点为分界线把区间划分成两部分和。注意中点是作为分界线不参与下一轮处理。查询一个点的最近点时,首先令最近距离为,然后在KD树中查...
阅读全文
摘要:刘雅琼PPT讲解链接:http://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html扩展KMP: 给出模板串A和子串B,长度分别为lenA和lenB,要求在线性时间内,对于每个A[i](0<=i<lenA), 求出A[i..lenA-1]与B的最长公共前缀长度,记为ex[i](或者说,ex[i]为满足A[i..i+z-1]==B[0..z-1]的最大的z值)。 扩展KMP可以用来解决很多字符串问题,如求一个字符串的最长回文子串和最长重复子串。【算法】 设next[i]为满足B[i..i+z-1]==B[0..z...
阅读全文
摘要:首先贴上 NBU 嘟嘟洒水车 大神的解题思路:http://www.acdream.net/problem.php?id=1042题目大意:(把物种和分类都看成节点。)有一颗未知树,一人每次询问两个叶子节点,另一个人回答其lca,判回答之间是否有矛盾。解法:将每条陈述按照lca的深度由深到浅排序,然后扫一遍开始并查集。比如说现在搞到这条陈述:x y a,那么查到xy的根节点 x_father y_father。由于是按照a的深度由深到浅搞的,所以a必然是x_father和y_father的祖先。那就分类讨论这样是否可能:一、a是x(y)_father之一:1、x_father和y_father
阅读全文
摘要:题目大意和思路同上题类似, 本题特殊点为其需要将多组满足要求的结果按递增全部输出。解题代码: View Code #include<stdio.h>#include<string.h>#include<stdlib.h>using namespace std;#define MAX(a,b) (a)>(b)?(a):(b)#define MIN(a,b) (a)<(b)?(a):(b)const int N = 50010;int M[N], n;int head[N], idx;struct node{ int max, sum;}D[N];s
阅读全文

浙公网安备 33010602011771号