数据结构
文章平均质量分 70
leolin_
这个作者很懒,什么都没留下…
展开
-
【后缀数组与统计】
后缀数组向来很强大,其中它的统计功能是一方面。下面以两道题目为例说明一下如何使用强大的后缀数组进行统计【例1】POJ 3415http://poj.org/problem?id=3415这题是求两串中长度>=K的子串的个数(可重复)做法:首先最正路的做法就是用后缀数组把两个串链接起来,中间加个没出现过的字符,对新串求heigh数组,我们先对遇到A的可以对前面与B的lcp进行相加,同原创 2012-04-10 10:18:50 · 894 阅读 · 0 评论 -
【线段树+O(nlgn)最长上升子序列】HDU 3564
the k-th number Xk means that we add number k at position Xk (0 注意插数的时候是插到当前序列里,也就是说不可能插到当前序列末尾,还有,这是可以不连续的!!!我还以为是LICS......囧#define N 100005struct node{ int l,r; int cnt;}t[N*4];void b原创 2012-02-14 16:19:03 · 1263 阅读 · 0 评论 -
【有根树的同构】ZOJ 1990/POJ 1635
有根树的同构的意思就是两棵树的形状一样,子树可以旋转,因此,当子树的子节点数相同就可以判断同构不用建树,只需要利用dfs时遇到'1'的时候回溯就行,开一个数组hash[i] = j表示子结点数为i(包括自己)的结点为j个0ms无压力int hash[801];//hash[i] = j表示子结点数为i(包括自己)的结点为j个int get1(){ int n = 1;原创 2012-02-23 15:55:12 · 927 阅读 · 1 评论 -
【线段树求LCIS】HDU 3308
注意查询时当左右两个区间可以合并的情况min(mid-x+1, t[id#define N 100005struct node{ int l,r; int lm,rm; int mx;}t[N*4+1000];int a[N+100];inline void up(int id){ t[id].lm = t[id<<1].lm; if(t[id原创 2012-02-14 10:41:12 · 501 阅读 · 0 评论 -
【线段树延迟更新】HDU 3275
以后再补解题报告,先贴代码http://acm.hdu.edu.cn/showproblem.php?pid=3275#define N 100005char str[N];int sum0[N*4],sum1[N*4];bool mark[N*4];void up(int id){ sum0[id] = sum0[id<<1] + sum0[id<<1|1]; sum原创 2012-02-14 06:58:14 · 523 阅读 · 0 评论 -
【线段树延迟更新】Codeforces Round #104 (Div. 1) E
#define N 1000005int c4[N*5],c7[N*5];int c47[N*5],c74[N*5];bool mark[N*5];char str[N];void up(int id){ c4[id] = c4[id<<1] + c4[id<<1|1]; c7[id] = c7[id<<1] + c7[id<<1|1]; c47[id] = ma原创 2012-02-13 19:27:28 · 638 阅读 · 0 评论 -
【LCA+树形DP】POJ 3417
参考了该blog的思路http://www.cppblog.com/Yuan/archive/2010/07/11/120101.html,orz...........#define N 100010struct edge{ int v; int len; int next;}e[2*N];int ecnt;int head[N];bool vis[N];原创 2012-02-08 17:57:59 · 826 阅读 · 0 评论 -
【RMQ】POJ 2452
#define N 50010int a[N];int max(int i,int j){return a[i]>a[j]?i:j;}int min(int i,int j){return a[i]>a[j]?j:i;}int dp1[20][N];//dp[i][j]表示从j开始,长度为2^i区间最大值(最小值)int dp2[20][N];int n,m;void init_rm原创 2012-02-07 15:17:58 · 773 阅读 · 1 评论 -
【RMQ】POJ 3264
开两个dp数组分别记录最大值和最小值就ok。#define N 50010int max(int a,int b){return a>b?a:b;}int dp1[20][N];int dp2[20][N];int f[N];int n,m;void init_rmq(){ int i,j; for(i=1;i<=n;i++){ dp1[0][i]原创 2012-02-07 13:00:08 · 435 阅读 · 0 评论 -
【二维树状数组】POJ 1195
求和的时候注意容斥原理ans = sum(x2,y2)-sum(x1-1,y2)-sum(x2,y1-1)+sum(x1-1,y1-1);#define N 1100int c[N][N];int lowbit(int x){ return x&(-x);}void add(int i,int j,int x){ int tmp; while(i<N){原创 2012-02-07 00:21:51 · 489 阅读 · 0 评论 -
【RMQ+离散化】POJ 3368
RMQ预处理的复杂度为O(nlgn),询问的复杂度为O(1)//离散化:从小到大记录这个序列每个值的起始位置、结束位置和频数#define N 100010int max(int a,int b){return a>b?a:b;}int dp[18][N];//dp[i][j]表示从j开始,长度为2^i区间最大值(最小值)int f[N];//以相同的数为一区间,记录频率int s[原创 2012-02-07 12:25:26 · 459 阅读 · 0 评论 -
【RMQ & LCA】
算法之LCA与RMQ问题1、 概述LCA(Least Common Ancestors),即最近公共祖先,是指这样一个问题:在有根树中,找出某两个结点u和v最近的公共祖先(另一种说法,离树根最远的公共祖先)。 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j转载 2012-02-07 03:20:24 · 486 阅读 · 0 评论 -
【二维树状数组】HDU 1892
注意树状数组的初始化,c[i][j] = lowbit(i)*lowbit(j)与add(i,j,1)等价!因为树状数组的lowbit作用是提取出x的最低位1.#define N 1100int c[N][N];int g[N][N];int lowbit(int x){ return x&(-x);}void add(int i,int j,int x){ in原创 2012-02-07 01:36:26 · 876 阅读 · 0 评论 -
【线段树】hdu 1754
树状数组不行呐,复杂度太高#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #in原创 2011-08-03 23:17:20 · 423 阅读 · 0 评论 -
【划分树】
划分树和归并树都是用线段树作为辅助的,原理是基于快排 和归并排序 的。划分树的建树过程基本就是模拟快排过程,取一个已经排过序的区间中值,然后把小于中值的点放左边,大于的放右边。并且记录d层第i个数之前(包括i)小于中值的放在左边的数。具体看下面代码注释。查找其实是关键,因为再因查找[l,r]需要到某一点的左右孩子时需要把[l,r]更新。具体分如下几种情况讨论:假原创 2011-08-18 02:08:04 · 1188 阅读 · 0 评论 -
【二维线段树】HDU 1823
很裸的一道二维线段树,第一次做,其实二维的线段树也就是树套树,先一维再第二维,第一、二维的操作都很类似。说回hdu这道题,有点水,提交的时候记得交c++,g++会wa死你!#define N 210struct node{ int al,ar; double mx;};struct node1{ int hl,hr; node subt[4000];原创 2012-02-16 17:04:53 · 2406 阅读 · 0 评论 -
【归并树—求第K小数】POJ 2104/HDU 2665
归并树 O(logn*logn*logn) for each query,很慢的说,划分树版http://blog.csdn.net/leolin_/article/details/6696801/*//1,建立归并树后我们得到了序列key[]的非降序排列,由于此时key[]内元素的rank是非递减的,因此key[]中属于指定区间[s,t]内的元素的rank也是非递减的,所以我们可以用原创 2012-02-15 11:40:56 · 739 阅读 · 0 评论 -
【单调栈】POJ 3250
第一次听说有单调栈这个东西,其实单调栈跟单调队列差不多,栈中的元素也有单调性,就拿这题来说,我们需要维护一个严格单调递减的栈sample:610 3 7 4 12 2栈中的变化如下:1010 310 710 7 41212 2stack s;int main(){ int n; while(scanf("%d",&n) !=-1){原创 2012-04-09 15:01:19 · 973 阅读 · 0 评论 -
【树形dp统计距离为k的点对】VK Cup 2012 Round 1 D. Distance in Tree
http://codeforces.com/contest/161/problem/D树形dp,很优美,利用了树的性质和dfs回溯...注意以防重复,所以要把计数提前到更新操作前#define N 50005LL dp[N][505];vector v[N];LL ans = 0;int n,k;void dfs(int u,int fa){ int i; d原创 2012-03-12 17:53:14 · 1109 阅读 · 1 评论 -
数据结构之树状数组
1、概述树状数组(binary indexed tree),是一种设计新颖的数组结构,它能够高效地获取数组中连续n个数的和。概括说,树状数组通常用于解决以下问题:数组{a}中的元素可能不断地被修改,怎样才能快速地获取连续几个数的和?2、树状数组基本操作传统数组(共n个元素)的元素修改和连续元素求和的复杂度分别为O(1)和O(n)。树状数组通过将线性结构转换成伪树状结构(线性结构只能逐个原创 2011-05-15 21:34:00 · 755 阅读 · 0 评论 -
【树状数组求第k小+并查集】POJ 2985
http://poj.org/problem?id=2985树状数组已经够神奇了,原来它还可以求第k小的元素........orz,位运算V5!#define N (1<<20)int c[N],rank[N],fa[N];int n,m;void init(){ int i; for(i=1;i<N;i++){ c[i] = 0;原创 2012-03-10 10:01:13 · 1214 阅读 · 0 评论 -
【树状数组求第k小】POJ 2892
又一次用到树状数组求第k小,注意边界情况#define N 50005int c[N];int lowbit(int x){ return x&(-x);}void add(int x,int v){ while(x<N){ c[x]+=v; x+=lowbit(x); }}int sum(int x){ int an原创 2012-03-10 10:47:08 · 653 阅读 · 0 评论 -
【bfs优先队列】POJ 2312
char g[333][333];int n,m;struct node{ int x,y; int step; friend bool operator <(node a,node b){ return a.step>b.step; }};node st,end;bool vis[333][333];int d[4][2] = {0,1原创 2012-03-06 13:07:41 · 500 阅读 · 0 评论 -
【bfs优先队列】POJ 3635
http://poj.org/problem?id=3635#define N 1005struct node{ int u; int len;};vector v[N];int n,m;int price[N];void add(int a,int b,int w){ node tmp; tmp.u = b; tmp.len = w;原创 2012-03-06 12:15:41 · 544 阅读 · 0 评论 -
【bfs优先队列/floodfill】POJ 2227
刘汝佳黑书P89例题,先把边界入队,取出最小的检查4个方向,如果小于当前的证明可以注水,注水完后更新高度为当前高度,入队;如果大于当前高度就直接入队。。。所以出队的元素都是不能注水的....黑书上说有floodfill算法,没研究过,应该类似这样吧LL ans;struct node{ int x,y; int h; friend bool operator < (n原创 2012-03-06 21:56:59 · 1229 阅读 · 0 评论 -
【逆序数】POJ 2188
这题也是求逆序数,只是题目描述有点诡异==!给出的是钩子的id,不是一对一的关系,所以要映射一下,喜欢上用归并求逆序数#define N 1010int a[N],b[N];int tmp[N];int sum;void merge_sort(int l,int mid,int r){ int i = l,j = mid+1,k = 1; while(i<=mid &&原创 2012-02-28 01:01:30 · 976 阅读 · 0 评论 -
【直线划分+逆序数】ZOJ 3574
左边交点从小到大排序,右边求逆序数,用归并求,注意要处理一下左边交点共点的情况,答案就是直线数+交点数+1,一不小心刷到rank2...ORZ#define N 30005struct node{ int l,r;}p[N];int a[N];int n;int tmp[N];int num;void merge_sort1(int l,int mid,int r)原创 2012-02-27 19:44:13 · 728 阅读 · 0 评论 -
【左偏树】HDU 1512/ZOJ 2334
推荐黄源河的论文http://wenku.baidu.com/view/515f76e90975f46527d3e1d5.html #define N 100010struct node{ int dis,v; int l,r;}k[N];int n,m,pre[N];void init(){ int i; for(i=0;i<=n;原创 2012-02-17 15:59:04 · 1219 阅读 · 0 评论 -
STL【Heap】
STL里面的堆操作一般用到的只有4个。他们就是make_heap();、pop_heap();、push_heap();、sort_heap();他们的头函数是include首先是make_heap();他的函数原型是:void make_heap(first_pointer,end_pointer,compare_function);一个参数是数组或向量的头指针,原创 2011-08-13 22:32:12 · 488 阅读 · 0 评论 -
【划分树】HDU 3473
题意就是求[l,r]中位数与其余元素差的绝对值再求和方法:用划分树求出中位数,询问的同时求出中位数左边元素和还有左边元素个数,因此这里需要增加一个数组suml[dep][i]表示深度为dep的一段区间里划分到左边的元素和,求出来后就可以算出右边元素和还有右边元素个数,最后的结果就是ans = rs-ls+mid*(lcnt-rcnt),具体看代码和注释。注意有可能溢出,所以凡是跟元素和有关原创 2012-02-16 14:24:12 · 817 阅读 · 0 评论 -
【splay树】hdu 3487
可以作为模板#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;#define LL原创 2012-01-22 03:30:04 · 789 阅读 · 0 评论 -
poj 3468【线段树+延迟优化】
经典线段树题目,如果用一般的深入到每个节点去修改值的方法会TLE,所以这里引入一个新名词“延迟优化”,意思是说每个节点线段有一个增量值inc,用来保存增量的,当当前区间等于要查询的区间就用当前区间的和sum+当前区间的增量inc*(t-s+1),否则就把增量传下去,而当前区间则加上这增量和并且inc 归零由于此时poj突然没有了这题,估计要改数据,所以提交不了,先上代码。线段树原创 2011-08-05 20:11:34 · 478 阅读 · 0 评论 -
【堆】poj 1441
#include #include #include #include #include #include #include #include #include #include #include #include #include #include原创 2011-08-15 15:27:22 · 476 阅读 · 0 评论 -
poj 2442【堆应用+STL Heap】
本题要维护两个大根堆,用来循环维护。。。注意STL heap里的复杂度#include #include #include #include #include #include #include #include #include #include #in原创 2011-08-14 17:11:09 · 627 阅读 · 0 评论 -
STL【priority_queue】
priority_queue 在头文件中,还定义了另一个非常有用的模板类priority_queue(优先队列)。优先队列与队列的差别在于优先队列不是按照入队的顺序出队,而是按照队列中元素的优先权顺序出队(默认为大者优先,也可以通过指定算子来指定自己的优先顺序)。prio原创 2011-08-03 04:19:15 · 776 阅读 · 0 评论 -
数据结构之堆
数据结构之堆1. 概述堆(也叫优先队列),是一棵完全二叉树,它的特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆)。它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等。二叉堆形状可参考维基百科2. 堆的基本操作堆是一棵完转载 2011-05-15 21:09:00 · 811 阅读 · 0 评论 -
ural 1306【priority_queue+堆查找中间值】
http://acm.timus.ru/problem.aspx?space=1&num=1306—— 一道不错的“水题”一开始用sort快排,结果到了test就MLE了。。。后来看了别人才知道可以用堆来做,今晚也花了整整一晚去研究用堆实现的priority_queue优先队原创 2011-08-03 04:53:30 · 800 阅读 · 0 评论 -
单调队列+STL deque
单调队列=双端队列!我们从最简单的问题开始:给定一个长度为N的整数数列a(i),i=0,1,...,N-1和窗长度k.要求: f(i) = max{a(i-k+1),a(i-k+2),..., a(i)},i = 0,1,...,N-1问题的另一种描原创 2011-08-06 15:14:56 · 3166 阅读 · 1 评论 -
poj2828【线段树】
可以从后往前看,那么pos就变成了前面有几个空位,线段树每个区间表示改区间空位有多少。#include #include #include #include #include #include #include #include #include #incl原创 2011-08-08 02:18:51 · 809 阅读 · 0 评论 -
ural 1126【单调队列基础】
http://acm.timus.ru/problem.aspx?space=1&num=1126虽说是简单的单调队列,但是足足折磨了我大半天!因为没接触过单调队列,所以刚开始时束手无策,可以用线段树,但你知道线段树的代码量。。。题意是给出一个数列,给出一个n,问你每n个原创 2011-08-06 15:16:20 · 610 阅读 · 0 评论