随笔分类 -  模版

各种模版
摘要:题意:求树上A,B两点路径上第K小的数分析:同样是可持久化线段树,只是这一次我们用它来维护树上的信息。我们之前已经知道,可持久化线段树实际上是维护的一个前缀和,而前缀和不一定要出现在一个线性表上。比如说我们从一棵树的根节点进行DFS,得到根节点到各节点的距离dist[x]——这是一个根-x路径上点与根节点距离的前缀和。利用这个前缀和,我们可以解决一些树上任意路径的问题,比如在线询问[a,b]点对的距离——答案自然是dist[a]+dist[b]-2*dist[lca(a,b)]。同理,我们可以利用可持久化线段树来解决树上任意路径的问题。DFS遍历整棵树,然后在每个节点上建立一棵线段树,某一棵线 阅读全文
posted @ 2013-10-09 20:56 z.arbitrary 阅读(2346) 评论(0) 推荐(0)
摘要:题意:完成两个操作:1.询问一个区间里第k小的数;2.修改数列中一个数的值。分析:线段树套平衡树,线段树中的每个节点都有一棵平衡树,维护线段树所记录的这个区间的元素。这样处理空间上是O(nlogn)的,因为线段树有logn层,每层的平衡树所记的节点总数都有n个。修改很容易想到,把所有包含要修改点的区间的平衡树都修改了就行了查询使用二分答案的方法// File Name: 2112.cpp// Author: Zlbing// Created Time: 2013年10月07日 星期一 18时24分39秒#include#include#include#include#include#inclu 阅读全文
posted @ 2013-10-09 18:56 z.arbitrary 阅读(1607) 评论(0) 推荐(0)
摘要:可持久化线段树也叫函数式线段树也叫主席树,其主要思想是充分利用历史信息,共用空间http://blog.sina.com.cn/s/blog_4a0c4e5d0101c8fr.html这个博客总结的挺好的!区间k大数问题对于没有修改的版本,我们可以先离散化然后对权值建树。结点存储的是该权值范围内出现元素的总次数。在线段树上找k大数时就像平衡树询问k大数一样根据结点上的信息往左或者往右走。现在可以利用函数式线段树维护权值出现数量,将数列中每个结点依次插入线段树,第r次插入后的线段树与第l-1次插入的线段树之“差”(对应结点的值相减,因为按权值建树结构是一样的)得到的线段树里进行上述的查找k大数操 阅读全文
posted @ 2013-10-06 19:26 z.arbitrary 阅读(5019) 评论(1) 推荐(0)
摘要:引用自HH大牛的模板http://www.notonlysuccess.com/index.php/sa/// File Name: suffix.cpp// Author: Zlbing// Created Time: 2013年09月04日 星期三 19时57分46秒#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;#define CL(x,v); memset(x,v,sizeof(x));#define I 阅读全文
posted @ 2013-09-05 21:06 z.arbitrary 阅读(774) 评论(0) 推荐(0)
摘要:匹配就是一个图中一堆没有端点的边的集合,求最大匹配就是求这个边集最大有多少条边。无论是任意图还是二分图,都有以下定理:当前匹配是最大匹配当且仅当不存在增广路。增广路的定义就是,一条包含奇数条边的路径,最前和最后的两条边都是非匹配边,且对于路径非两端的点,都连接着一条匹配边和非匹配边。求图的匹配的算法就是不断地找增广路,把增广路上的匹配边变成非匹配边,非匹配边变成匹配边。对于二分图来说,只要从一个没有被匹配到的点开始bfs(dfs)一下就能找到增广路(如果确实有增广路)。但是对于任意图来说,从一个没有被匹配到的点开始bfs(dfs)不一定能找到,能不能找到取决于遍历的顺序。于是,为了使任意图可以 阅读全文
posted @ 2013-08-31 14:23 z.arbitrary 阅读(2305) 评论(0) 推荐(1)
摘要:在线LCA如求A,B两点的LCA,先计算出各个结点的深度d[],然后,通过递推公式求出各个结点的2次方倍的祖先p[],假设d[A] > d[B],则找到d[p[A][i]] == d[B]也就是A的某一祖先与B深度相同,然后,u = p[A][i],通过p[u][i] 与p[B][i]比较找出LCA(巧妙的利用二进制).(p[a][b] 表示与a的距离为2^b的祖先,则p[a][0]表示为a的父亲。如 a->b->c->d->e,a为根, 则p[e][2] 为a)递推公式:p[a][b] = p[p[a][b - 1]][b - 1]/* 2^17=131072; 阅读全文
posted @ 2013-08-21 16:39 z.arbitrary 阅读(550) 评论(0) 推荐(0)
摘要:LCA离线算法它需要一次输入所有的询问,然后有根节点开始进行深度优先遍历(DFS),在深度优先遍历的过程中,进行并查集的操作,同时查询询问,返回结果。题意:求A ,B两点的最近公共祖先分析:dfs+并查集// File Name: 1330.cpp// Author: Zlbing// Created Time: 2013年08月18日 星期日 16时11分18秒#include#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;# 阅读全文
posted @ 2013-08-19 16:32 z.arbitrary 阅读(181) 评论(0) 推荐(0)
摘要:点操作:splay树可以一个一个的插入结点,这样的splay树是有序树,结点权值大于左儿子小于右儿子这样就是点操作区间操作:还有就是可以自己建树,这样的splay树就不是按权值的有序树,它不满足结点权值大于左儿子小于右儿子,,但是它也是有顺序的,无论怎么伸展,把它的结点中序遍历结果就是原来的数组顺序。因此自己建树可以操作区间!点操作模板// File Name: ACM/bzoj/1208.cpp// Author: Zlbing// Created Time: 2013年08月08日 星期四 16时33分53秒#include#include#include#include#include# 阅读全文
posted @ 2013-08-12 15:28 z.arbitrary 阅读(5983) 评论(2) 推荐(1)
摘要:题意:有N 个点,M条边,加一条边,求割边最少。(有重边)分析:先求双连通分量,缩点形成一个生成树,然后求这个的直径,割边-直径即是答案因为有的图上可能有重边,这样不好处理。我们记录每条边的标号(一条无向边拆成的两条有向边标号相同)这样就能限制不走一样的边而能走重边!// File Name: 1002.cpp// Author: Zlbing// Created Time: 2013年08月02日 星期五 18时16分10秒#pragma comment(linker,"/STACK:102400000,102400000")#include#include#includ 阅读全文
posted @ 2013-08-04 11:26 z.arbitrary 阅读(1416) 评论(0) 推荐(0)
摘要:题解:http://www.notonlysuccess.com/index.php/segment-tree-complete/题意:求矩形周长分析:与面积不同的地方是还要记录竖的边有几个(numseg记录)也就是[记录线段树被覆盖的区间有多少个],并且当边界重合的时候需要合并(用lbd和rbd表示边界来辅助)线段树操作:update:区间增减 query:直接取根节点的值// File Name: 1177.cpp// Author: Zlbing// Created Time: 2013/7/20 19:53:20#include#include#include#include#incl 阅读全文
posted @ 2013-07-20 20:56 z.arbitrary 阅读(314) 评论(0) 推荐(0)
摘要:题意:求矩形面积并分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化!把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区间内被覆盖的线段的长度总和这里线段树的一个结点并非是线段的一个端点,而是该端点和下一个端点间的线段,所以题目中r+1,r-1的地方可以自己好好的琢磨一下详细分析下扫描线第一次完全看懂扫描线.像这题的样例:这么两个矩形,现在要求它的面积并.假设我门将横边座位扫描线,即每个矩形有两条扫描线,下扫描线,下扫描线,每条扫描线我们用结构体const int MAXN=250;struct seg{ dou... 阅读全文
posted @ 2013-07-20 17:06 z.arbitrary 阅读(481) 评论(0) 推荐(0)
摘要:无源无汇可行流以前写的最大流默认的下界为0,而这里的下界却不为0,所以我们要进行再构造让每条边的下界为0,这样做是为了方便处理。对于每根管子有一个上界容量up和一个下界容量low,我们让这根管子的容量下界变为0,上界为up-low。可是这样做了的话流量就不守恒了,为了再次满足流量守恒,即每个节点"入流=出流”,我们增设一个超级源点ss和一个超级终点tt。我们开设一个数组du[]来记录每个节点的流量情况。du[i]=in[i](i节点所有入流下界之和)-out[i](i节点所有出流下界之和)。当du[i]大于0的时候,ss到i连一条流量为du[i]的边。当du[i]小于0的时候,i到t 阅读全文
posted @ 2013-06-05 20:11 z.arbitrary 阅读(248) 评论(0) 推荐(0)
摘要:题意:给n个点,及m根pipe,每根pipe用来流躺液体的,单向的,每时每刻每根pipe流进来的物质要等于流出去的物质,要使得m条pipe组成一个循环体,里面流躺物质。并且满足每根pipe一定的流量限制,范围为[Li,Ri].即要满足每时刻流进来的不能超过Ri(最大流问题),同时最小不能低于Li。分析:无源汇有上下界的最大流建图:以前写的最大流默认的下界为0,而这里的下界却不为0,所以我们要进行再构造让每条边的下界为0,这样做是为了方便处理。对于每根管子有一个上界容量up和一个下界容量low,我们让这根管子的容量下界变为0,上界为up-low。可是这样做了的话流量就不守恒了,为了再次满足流量守 阅读全文
posted @ 2013-06-05 18:16 z.arbitrary 阅读(1212) 评论(0) 推荐(0)
摘要:好的讲解manacher算法的文章,图文并茂。http://blog.csdn.net/ggggiqnypgjg/article/details/6645824题解来源:http://blog.sina.com.cn/s/blog_6fa65cf90100s3sg.html题意:求给定串的最长回文子串(2009多校题目)分析:枚举每个点向左向右扩展,看最远能扩展到哪儿.但是普通的枚举是n^2的,肯定超时。现在我们想kmp或扩展kmp一样,给字符串定义一个nex数组,nex[i]表示以i为中心最远能向右扩展的长度,使得s[i – nex[i] + 1……. i + nex[i]- 1]形成的回文 阅读全文
posted @ 2013-05-09 13:34 z.arbitrary 阅读(194) 评论(0) 推荐(0)
摘要:http://www.notonlysuccess.com/index.php/segment-tree-complete/comment-page-2/#comment-4139题意:给一组数据,有两个询问,一种是给区间[a,b]上每个数加c,另一种是求区间[a,b]的和!#include <cstdio>#include <algorithm>using namespace std; #define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1#define LL long 阅读全文
posted @ 2013-05-02 13:30 z.arbitrary 阅读(746) 评论(0) 推荐(0)
摘要:const int SIGMA_SIZE = 26;const int MAXNODE = 11000;const int MAXS = 150 + 10;map<string,int> ms;//ms是为了满足特殊要求,比如模板串相同时struct ACautomata { int ch[MAXNODE][SIGMA_SIZE]; int f[MAXNODE]; // fail函数 int val[MAXNODE]; // 每个字符串的结尾结点都有一个非0的val int last[MAXNODE]; // 输出链表的下一个结点 int cnt[MAXS]; int sz... 阅读全文
posted @ 2013-03-19 19:38 z.arbitrary 阅读(1258) 评论(0) 推荐(0)
摘要://f[i+1]是求与p[i]的下一个匹配的后一个数的下标int f[MAXN];void getFail(char *p,int *f){ int m=strlen(p); f[0]=f[1]=0; for(int i=1;i<m;i++){ int j=f[i]; while(j&&p[i]!=p[j])j=f[j]; f[i+1]=p[i]==p[j]?j+1:0; }}void find(char *T,char *p,int *f){ int n=strlen(T); int m=strlen(p); ... 阅读全文
posted @ 2013-03-17 19:54 z.arbitrary 阅读(171) 评论(0) 推荐(0)
摘要:void out(int a) { if(a < 0) {putchar('-'); a = -a;} if(a >= 10)out(a / 10); putchar(a % 10 + '0'); } int in() { int flag = 1; char ch; int a = 0; while((ch = getchar()) == ' ' || ch == '\n'); if(ch == '-') flag = -1; else a += ch - '0'; whil... 阅读全文
posted @ 2013-03-16 15:53 z.arbitrary 阅读(482) 评论(0) 推荐(0)
摘要:Trie树也叫前缀树用来保存字符串集刘汝佳新书----训练指南前缀树模版const int maxnode = 4000 * 100 + 10;const int sigma_size = 26;// 字母表为全体小写字母的Triestruct Trie { int ch[maxnode][sigma_size]; int val[maxnode]; int sz; // 结点总数 void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } // 初始时只有一个根结点 int idx(char c) { return c - '. 阅读全文
posted @ 2013-03-14 19:50 z.arbitrary 阅读(153) 评论(0) 推荐(0)
摘要:http://www.notonlysuccess.com/index.php/segment-tree-complete/线段树功能:update:单点增减 query:区间求和#include <cstdio> #define lson l , m , rt << 1#define rson m + 1 , r , rt << 1 | 1const int maxn = 55555;int sum[maxn<<2];void PushUP(int rt) { sum[rt] = sum[rt<<1] + sum[rt<< 阅读全文
posted @ 2013-03-12 11:37 z.arbitrary 阅读(179) 评论(0) 推荐(0)