seg

[SHOI2012]魔法树

眉间皱痕 提交于 2019-12-02 02:59:59
洛咕 题意:n个节点的树,每个点的初始点权为0,两种操作,一个是将 \((u,v)\) 路径上的每个点的点权加上 \(d\) ,一个是询问以 \(x\) 节点为根的子树的权值和. \(n,m<=100000.\) 树链剖分+线段树模板题.操作一是区间增加,操作二是区间查询. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #include<map> #include<set> #define ll long long using namespace std; inline int read(){ int x=0,o=1;char ch=getchar(); while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar(); if(ch=='-')o=-1,ch=getchar(); while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x*o; } const int N=100005; int tot,head[N],nxt[N<<1],to[N<<1]; inline void add(int a,int b){ nxt[++tot

[HEOI2016/TJOI2016]树

吃可爱长大的小学妹 提交于 2019-12-02 02:53:02
洛咕 题意:解决这样一个问题:给定一颗有根树,根为 \(1\) ,有以下两种操作: 1. 标记操作:对某个结点打上标记.(在最开始,只有结点 \(1\) 有标记,其他结点均无标记,而且对于某个结点,可以打多次标记.) 2. 询问操作:询问某个结点最近的一个打了标记的祖先.(这个结点本身也算自己的祖先). \(n,m<=100000.\) 分析:每个节点的权值就是其最近的一个打了标记的祖先的深度,显然,初始每个节点的权值都为1,然后树链剖分后线段树维护区间最大值. 对于每一次修改操作,如果这个节点之前没被标记,就单点修改权值. 对于一次询问操作,直接查询 \(x\) 到根节点路径上的权值最大值即可. 然后我就愉快地过了样例,交一发,发现只能过最后一个点.然后搞了半个小时才发现我这样输出的是该节点最近的一个打了标记的祖先的深度,所以只要根据这个深度再树上倍增一下就能求出编号了.(最后一个点为什么能过??显然,是因为这棵树是一条链,深度=编号). #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #include<map> #include<set> #define ll long long using namespace

DISQUERY - Distance Query

拟墨画扇 提交于 2019-12-01 23:25:09
洛咕 题意:给定有 \(n\) 个节点的树, 树上边有边权. 再给定 \(q\) 组询问, 每次询问两个点路径上的最小值和最大值. \(n,q<=100000.\) 询问树上路径点权的最值是树链剖分的模板题,然后本题给的是边权,就化边权为点权,从1号点为根 \(dfs\) 的时候,把 \(w[u][v]\) 这条边的边权给节点 \(v\) .然后就可以按照模板来做了 \(???\) 但是,这时根节点的权值为0,如果一条路径经过了根节点,其最小值会是根节点的权值0,所以我把根节点的权值赋值为 \(-1\) ,然后维护线段树区间最小值取 \(min\) 操作的时候,特判 \(-1\) 的情况(自己写个 \(min\) 函数就好了),因为边权为正(虽然题目好像并没有说明,当做默认了),所以对最大值的答案是没有影响的.然后就可以按照模板来做了 \(???\) 但是,会发现连样例一的第一组询问都过不去,注意到如果一组询问 \((x,y)\) ,设 \(lca=LCA(x,y)\) .查询答案的时候, \(lca\) 的权值对答案产生了影响,因为这条路径会经过 \(lca\) ,但是因为路径不会经过 \(lca\) 与 \(fa[lca]\) 这条边,所以实际上 \(lca\) 的权值是不能被考虑贡献的,所以我极其暴力地写了个线段树的单点修改操作,查询前把 \(lca\) 的权值改为 \(-1

CF707D Persistent Bookcase 可持久化线段树

微笑、不失礼 提交于 2019-12-01 23:07:52
code: #include <bits/stdc++.h> #define M 1004 #define N 100005 #define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout) using namespace std; bitset<M>v[N],uni,oo; int rt[N]; namespace seg { #define lson t[x].ls #define rson t[x].rs int tot; int newnode() { return ++ tot; } struct Node { int ls,rs,id,sum; }t[N*40]; int update(int x,int l,int r,int p,int v) { int now=newnode(); t[now]=t[x]; if(l==r) { t[now].id=v; return now; } int mid=(l+r)>>1; if(p<=mid) { t[now].ls=update(lson,l,mid,p,v); } else { t[now].rs=update(rson,mid+1,r,p,v); } t[now].sum=t[t[now].ls].sum+t[t[now].rs]

【扫描边】学习笔记

▼魔方 西西 提交于 2019-12-01 16:54:05
【模板】扫描边 题目描述 求 n 个矩形的面积并。 输入格式 第一行一个正整数 n n。 接下来 n n 行每行四个非负整数 x_1, y_1, x_2, y_2 x 1 ​ , y 1 ​ , x 2 ​ , y 2 ​ ,表示一个矩形的左下角坐标为 (x_1, y_1) ( x 1 ​ , y 1 ​ ),右上角坐标为 (x_2, y_2) ( x 2 ​ , y 2 ​ )。 输出格式 一行一个正整数,表示 n n 个矩形的并集覆盖的总面积。 输入输出样例 输入 #1 复制 2 100 100 200 200 150 150 250 255 输出 #1 复制 18000 说明/提示 对于 20\% 2 0 % 的数据, 1 \le n \le 1000 1 ≤ n ≤ 1 0 0 0。 对于 100\% 1 0 0 % 的数据, 1 \le n \le 10^5, 0 \le x_1 < x_2 \le 10^9, 0 \le y_1 < y_2 \le 10^9 1 ≤ n ≤ 1 0 5 , 0 ≤ x 1 ​ < x 2 ​ ≤ 1 0 9 , 0 ≤ y 1 ​ < y 2 ​ ≤ 1 0 9。 扫描线的思想主要思想就是分割图形。 扫描线的方向没有规定,这里用从左到有说明扫描线是如何分割图形的。 我们可以将一个矩形转化成两条边,及左边和右边平行y轴的两条边。

xen块设备体系结构(5)

不想你离开。 提交于 2019-12-01 12:09:54
blktap 又回到那个问题,I/O请求从前端到后端blkback之后,如何从blkback到大tapdisk2进程? pvops/Drivers/Xen/Blktap/ 下面是blktap的驱动代码,其中blktap的设备结构如下: struct blktap { int minor; unsigned long dev_inuse; struct blktap_ring ring; struct blktap_device device; struct blktap_page_pool *pool; wait_queue_head_t remove_wait; struct work_struct remove_work; char name[BLKTAP2_MAX_MESSAGE_LEN]; struct blktap_statistics stats; }; 根据目前的理解,blktap包含了四个模块:blktap_device, blktap_ring, blktap_sysfs, blktap_control static struct blktap_page_pool *default_pool 定义了blktap驱动和tapdisk2(??)进程的消息交换的内存页空间?? (个人推测,待求证) blktap_page_pool_init 为slab

Codeforces Round #321 (Div. 2)

爱⌒轻易说出口 提交于 2019-12-01 08:54:12
A. Kefa and First Steps 求最长递增连续子序列。 B. Kefa and Company 排序二分就行了。 #include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e5 + 7; struct P { ll m, s; P(ll m = 0, ll s = 0): m(m), s(s) {} bool operator < (const P &rhs) const { return m < rhs.m; } } p[N]; ll sum[N]; int main() { int n; ll d; scanf("%d%lld", &n, &d); for (int i = 1; i <= n; i++) scanf("%lld%lld", &p[i].m, &p[i].s); sort(p + 1, p + n + 1); ll ans = 0; for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + p[i].s; for (int i = 1; i <= n; i++) { int pos = upper_bound(p + i + 1, p + n + 1, P(d + p[i].m - 1, 0)) -

BZOJ4817 [SDOI2017]树点涂色

被刻印的时光 ゝ 提交于 2019-12-01 05:14:36
Bob有一棵$n$个点的有根树,其中$1$号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。 定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。 Bob可能会进行这几种操作: 1 x 把点$x$到根节点的路径上所有的点染上一种没有用过的新颜色。 2 x y 求$x$到$y$的路径的权值。 3 x 在以$x$为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。 Bob一共会进行$m$次操作。 $n,m leqslant 10^5$。 题解 这道题我是按着LCT的标签找的,然而看到这道题的时候满脑子都是树剖……根本看不出哪里要用LCT……个人觉得这题还是蛮巧妙的。 首先,如果我们把同一种颜色的点放到LCT的一棵Splay中去,那么可以发现,1操作恰好就是LCT的 access 操作了。 对于一个点,他到根节点的权值,也就是LCT中这个点到根节点的实链的条数。记$f[i]$表示$i$号节点到根的权值。由这个权值的性质,我们不难得到,对于两个点$x$与$y$,$x$到$y$的路径上的权值为$$f[x]+f[y]-2f[lca(x,y)]+1$$ 于是第二个操作也解决了。 第三个操作,我们不难想到把dfs序抽出来,在线段树上查询即可。 最后我们还有一个问题,也就是$f$数组该如何维护。其实不难想到,在 access

BZOJ4817 [SDOI2017]树点涂色

六眼飞鱼酱① 提交于 2019-12-01 05:05:34
Bob有一棵$n$个点的有根树,其中$1$号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。 定义一条路径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。 Bob可能会进行这几种操作: 1 x 把点$x$到根节点的路径上所有的点染上一种没有用过的新颜色。 2 x y 求$x$到$y$的路径的权值。 3 x 在以$x$为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。 Bob一共会进行$m$次操作。 $n,m leqslant 10^5$。 题解 这道题我是按着LCT的标签找的,然而看到这道题的时候满脑子都是树剖……根本看不出哪里要用LCT……个人觉得这题还是蛮巧妙的。 首先,如果我们把同一种颜色的点放到LCT的一棵Splay中去,那么可以发现,1操作恰好就是LCT的 access 操作了。 对于一个点,他到根节点的权值,也就是LCT中这个点到根节点的实链的条数。记$f[i]$表示$i$号节点到根的权值。由这个权值的性质,我们不难得到,对于两个点$x$与$y$,$x$到$y$的路径上的权值为$$f[x]+f[y]-2f[lca(x,y)]+1$$ 于是第二个操作也解决了。 第三个操作,我们不难想到把dfs序抽出来,在线段树上查询即可。 最后我们还有一个问题,也就是$f$数组该如何维护。其实不难想到,在 access

牛客小白月赛9-红球进黑洞(异或线段树)

故事扮演 提交于 2019-12-01 05:04:59
题意: 操作 \(1\) :求 \([l,r]\) 区间和。 操作 \(2\) :区间 \([l,r]\) 的数异或上 \(k\) 。 分析: 对区间进行位运算是没啥公式的,所以要考虑对数的每一位建线段树,记录每一位 \(1\) 出现的次数。询问的时候求出每一位的贡献即可。 线段树维护的是每一位 \(1\) 的出现次数。 区间异或:首先如果 \(k\) 的 \(i\) 位为 \(0\) ,则异或值不变,否则异或 \(i\) 位的区间 \([l,r]\) 相当于将这个区间的 \(0\) 变成 \(1\) , \(1\) 变成 \(0\) 。 区间或:或上某一位1才有意义 区间与:与上某一位0才有意义 #include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e5 + 5; const int mod = 1e9 + 7; int n, q, w[N]; int seg[N << 2][19], lazy[N << 2][19]; int opt, res, x, y, k; LL ans, base; void build(int rt, int l, int r, int o) { if (l == r) { seg[rt][o] += ((w[l] >> o) & 1);