
线段树
stdwal
天演在化,功成在学。知海无涯,见花问道。
展开
-
HDU1698-Just a Hook
线段树的成段更新问题,这里可以精简的删去build和query函数。#include <cstdio>#define lchild rt << 1, l, m#define rchild rt << 1 | 1, m + 1, rconst int maxn = 1 << 18;int tree[maxn];int lazy[maxn];int n;void push_up(int rt) {原创 2016-08-15 17:07:59 · 278 阅读 · 0 评论 -
POJ2104-K-th Number
静态区间求第K大的值,有多种方式。 首先可以用分桶法和平方分割求解,将数据分为多个桶,每个桶分别处理桶内的数据以降低复杂度。#include <cstdio>#include <vector>#include <algorithm>using namespace std;const int maxn = 100000 + 10;const int B = 1000;int a[maxn];原创 2016-08-27 22:01:34 · 411 阅读 · 0 评论 -
HDU1754-I Hate It
典型的线段树问题,坑点在于有多组测试数据…#include <cstdio>#include <algorithm>using namespace std;const int maxn = 1 << 18;int n, dat[2*maxn-1];void init(int n_) { n = 1; while (n < n_) { n *= 2; }原创 2016-08-09 15:48:32 · 328 阅读 · 0 评论 -
POJ2991-Crane
维护一个线段树和一个相对变化角度的数组,每个线段树节点表示从左子树到右子树的向量,每条线段(叶子节点)一经初始化后就不改变vx, vy,只需更新父节点即可。#include <cstdio>#include <cmath>const double pi = acos(-1.0);const int st_size = (1 << 15) - 1;const int maxn = 10000 +原创 2016-08-15 11:11:13 · 465 阅读 · 0 评论 -
POJ3468-A Simple Problem with Integers
一道经典的线段树区间更新的题,你值得拥有!#include <cstdio>#define lchild rt << 1, l, m#define rchild rt << 1 | 1, m + 1, rconst int maxn = 1 << 18;long long tree[maxn];long long lazy[maxn];int n;void push_up(int rt) {原创 2016-08-15 14:47:35 · 222 阅读 · 0 评论 -
POJ2777-Count Color
线段树真是一种优雅的解决方案。 将30种颜色用二进制编码,然后用线段树每个节点维护颜色的种类。void push_up(int rt) { tree[rt] = tree[rt<<1] | tree[rt<<1|1];}巧妙的位运算使得通过每个二进制位即可知道在这个区域内一共有多少种颜色。另外用lazy数组延迟标记以优化算法速度。需要注意的是输入的a,b需要比较一下,因为可能会存在a >原创 2016-11-08 20:50:17 · 305 阅读 · 0 评论 -
POJ2828-Buy Tickets
用线段树维护队伍内剩余的空位和位置里人的val值,然后从后往前给每个人安排空位,如果有人就往后移动。 神奇的是这道题允许最后输出存在空格哟!#include <cstdio>#define lchild rt << 1, l, m#define rchild rt << 1 | 1, m + 1, rconst int maxn = 200000 + 5;const int sz = 1 <<原创 2016-11-07 21:46:43 · 329 阅读 · 0 评论 -
POJ2886-Who Gets the Most Candies?
先打表求反素数,这些反素数表示能够得到最多的糖果的回合数。 因此只要找出n以内最大的反素数,就表示在那个回合出局的人拿到最多的糖果,糖果数为该反素数的因子个数。 用线段树维护圈内的剩余人数和原来的位置,用类似约瑟夫环的方式求出每个人的相对位置,更新线段树,找出在那一个回合出局的人。 tree[1]表示剩下的人数。 当某个人手中的数字为负时,有可能会极小,因此要注意使余数为正。#include原创 2016-11-10 20:01:07 · 266 阅读 · 0 评论 -
Ural1987-Nested Segments
题目上说每两条线段要么没有公共点,要么完全覆盖,而且又规定了输入顺序,因此对于某个点来说后输入的长度一定短,所以用线段树做区间更新即可。 由于数字很大,需要先做一个离散化,把线段的点和询问的点离散后更新线段树。#include <cstdio>#include <map>using namespace std;#define lchild rt << 1, l, m#define rchild原创 2016-11-20 09:18:47 · 455 阅读 · 0 评论