摘要:
HDU_4010 这个题目由于需要Cut和Join,所以需要用link-cut-tree来写。 无论是Cut还是Join,都涉及到一个基本的操作,就是把一个节点变成根(makeroot),如果能把makeroot这个操作写成功的话,Cut和Join就比较好完成了。 实际上在进行access(x)的操作之后,如果我们想将x作为根,只需要将这条路径上的边的父子关系都“反向”即可,那么便只要将x旋转到根,然后将这棵splay以及其子树上左右儿子的位置交换,也就是打一个rev(reverse)的标记就可以了。 此外,对于一些细节也需要注意,比如某些操作中x如果和y相等的话是否需要特判一下。#inclu 阅读全文
摘要:
POJ_2763 用link-cut-tree或者树链剖分都可以,只要支持单点修改和区间求和就可以了。但后面看dicuss里面说是树状数组和LCA,但由于这两个东西我暂时都没研究过,所以就没再深究这种解法了。#include<stdio.h>#include<string.h>#define MAXD 100010#define MAXM 200010int N, Q, S, first[MAXD], e, next[MAXM], v[MAXM], w[MAXM], q[MAXD], dep[MAXD];struct Edge{ int x, y, z;}edge[MA 阅读全文
摘要:
POJ_3237 用link-cut-tree或者树链剖分都可以,为了处理negate操作,出了lazy标记外可以做两个标记max、min,在执行negate时,令max=-min、min=-max即可。#include<stdio.h>#include<string.h>#define MAXD 100010#define MAXM 200010#define INF 0x7fffffffint N, q[MAXD], first[MAXD], e, next[MAXM], v[MAXM], w[MAXM], dep[MAXD];struct Edge{ int x, 阅读全文
摘要:
SPOJ_2798 如果用link-cut-tree写的话,只要维护col(节点的颜色)和sum(子树中black节点的数量)两个标记即可。染色的时候将对应节点splay到根然后修改,查询的时候先进行access(v)的操作,之后找到这棵splay的根再递归查找即可,如果根结点的sum值为0,则输出-1。#include<stdio.h>#include<string.h>#define MAXD 100010#define MAXM 200010int N, Q, q[MAXD], first[MAXD], e, next[MAXM], v[MAXM];struct 阅读全文
摘要:
SPOJ_913 这个题目应该也可以树链剖分去做,只不过感觉在KTH这个操作还是用link-cut-tree更好写一些。#include<stdio.h>#include<string.h>#define MAXD 10010#define MAXM 20010int N, q[MAXD], first[MAXD], e, next[MAXM], v[MAXM], w[MAXM];struct Splay{ int pre, ls, rs, size, sum, key; bool root; void update(); void zig(int ); void za 阅读全文
摘要:
SPOJ_6779 这个题目和GSS1的思想是一样的,只不过由于变成了树,所以可以先用树链剖分先将树划分成若干棵线段树再进行求解。 另外我的代码写得确实比较挫,推荐一份效率比较高的用动态树写的代码:http://ideone.com/wA3Pr。View Code // 轻重边树链剖分#include<stdio.h>#include<string.h>#define MAXD 100010#define MAXM 200010#define INF 0x3f3f3f3fint N, a[MAXD], mc[4 * MAXD], lc[4 * MAXD], rc[4 * 阅读全文
摘要:
URAL_1471 这个题目可以用树链剖分做,另外推荐一个讲树链剖分通俗易懂的博客:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html。#include<stdio.h>#include<string.h>#define MAXD 50010#define MAXM 100010int N, Q, first[MAXD], next[MAXM], v[MAXM], e;int fa[MAXD], dep[MAXD], son[MAXD], size[MAXD], w[MAXD], top[MAXD], cnt;int 阅读全文
摘要:
HDU_3966 树链剖分的题目,推荐一个讲树链剖分通俗易懂的博客:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html。#include<stdio.h>#include<string.h>#define MAXD 50010#define MAXM 100010int N, M, Q, first[MAXD], e, next[MAXM], v[MAXM];int fa[MAXD], dep[MAXD], size[MAXD], son[MAXD], top[MAXD], w[MAXD], cnt;int a[MA 阅读全文
摘要:
SPOJ_375 树链剖分的处女作终于AC啦,O(∩_∩)O哈哈~ 思想是从这篇博客里面学来的:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html,上面讲得通俗易懂。只不过我在预处理的时候是用他说的避免暴栈的bfs方式来做的。#include<stdio.h>#include<string.h>#define MAXD 10010#define MAXM 20010#define NINF 0xc3c3c3c3int N, cnt, first[MAXD], e, next[MAXM], v[MAXM], fa[MA 阅读全文
摘要:
SPOJ_4487 其实这个题目和GSS1是差不多的,只不过由于有增加和删除的操作,这样用线段树就搞不定了,因此可以维护一个splay来实现这些操作。 但是一开始我写出的程序总是TLE,而和网上一些AC的程序对照之后发现无非有两点很不同的地方,一个是他们都用了结构体,另一个是他们都用了指针。在百思不得其解之际,我把以前的若干个数组仿照一个AC的程序写成了结构体,就像下面这样:struct Splay{ int left, right, pre, size, sum, mc, key, lc, rc; #define left(x) sp[x].left #define r... 阅读全文