BZOJ4009 权限题

真的不想再写一遍了

大佬blog

假设有果实$(x, y)$,询问$(a, b)$,用$st_i$表示$i$的$dfs$序,用$ed_i$表示所有$i$的子树搜完的$dfs$序,那么果实对询问产生贡献只会有两种情况:

1、这个果实表示的区间是一条链

  不妨假设$dep_x < dep_y$,记$z$为$x$到$y$的树链上的从$x$向下走的第一个点,画个图可以发现$(a, b)$需要满足:

    $st_a \in [1, st_z - 1] \cup [ed_z + 1, n], \ st_b \in [st_y, ed_y]$,其中$(a, b)$可以互换。

2、这个果实表示的链是一条先向上再向下的纯正的树链

  仍然画个图发现$(a, b)$需要满足:$st_a \in [st_x, ed_x], \ st_b \in [st_y, ed_y]$, $(a, b)$仍然可以互换。

对于每一个询问$(a, b)$,只要看一看有多少果实满足上面两种选一种的条件,然后求个$k$小就好了。

发现这其实是一个在二维矩阵中动态加点求$k$小的问题,这时候$KDTree$就出现了,然而我不会……

考虑扫描线降维,一个矩阵根据$x$坐标拆成两条线然后排个序扫一扫,每一次根据询问的点的位置进行加入删除的调整然后求个$k$小就好了。

也就是说只要写一个支持在一条线上区间加区间减然后求$k$小的数据结构就好了,我们需要一个外层权值内层下标的线段树兹磁这个操作。

瓶颈在于树套树的$O(nlog^2n)$。

最好标记永久化一下。

Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int N = 4e4 + ;
const int M = 3e7 + ;
const int Lg = ; int n, m, qn, lcnt = , mx = , num[N], tot = , head[N];
int dfsc = , st[N], ed[N], fa[N][Lg], dep[N], ans[N]; struct Edge {
int to, nxt;
} e[N << ]; inline void add(int from, int to) {
e[++tot].to = to;
e[tot].nxt = head[from];
head[from] = tot;
} struct Line {
int pos, x, y, v, type; inline Line (int nowPos = , int nowX = , int nowY = , int nowV = , int nowType = ) {
pos = nowPos, x = nowX, y = nowY, v = nowV, type = nowType;
} friend bool operator < (const Line &u, const Line &v) {
return u.pos < v.pos;
} } a[N << ]; inline void addLine(int l1, int r1, int l2, int r2, int v) {
a[++lcnt] = Line(l1, l2, r2, v, );
a[++lcnt] = Line(r1 + , l2, r2, v, -);
} struct Querys {
int x, y, k, id; friend bool operator < (const Querys &u, const Querys &v) {
return u.x < v.x;
} } q[N]; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} inline void swap(int &x, int &y) {
int t = x; x = y; y = t;
} void dfs(int x, int fat, int depth) {
fa[x][] = fat, dep[x] = depth, st[x] = ++dfsc;
for(int i = ; i <= ; i++)
fa[x][i] = fa[fa[x][i - ]][i - ];
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fat) continue;
dfs(y, x, depth + );
}
ed[x] = dfsc;
} inline int getPos(int x, int stp) {
int res = x;
for(int i = ; i >= ; i--)
if((stp >> i) & ) res = fa[res][i];
return res;
} namespace InSegT {
struct Node {
int lc, rc, sum;
} s[M]; int nodeCnt = ; #define lc s[p].lc
#define rc s[p].rc
#define sum(p) s[p].sum
#define mid ((l + r) >> 1) void modify(int &p, int l, int r, int x, int y, int v) {
if(!p) p = ++nodeCnt; if(x <= l && y >= r) {
sum(p) += v;
return;
} if(x <= mid) modify(lc, l, mid, x, y, v);
if(y > mid) modify(rc, mid + , r, x, y, v);
} int query(int p, int l, int r, int x) {
if(l == r) return sum(p);
int res = sum(p);
if(x <= mid) res += query(lc, l, mid, x);
else res += query(rc, mid + , r, x);
return res;
} #undef lc
#undef rc
#undef sum
} namespace OutSegT {
using namespace InSegT; #define lc p << 1
#define rc p << 1 | 1 int root[N << ]; void ins(int p, int l, int r, int x, int y, int pos, int type) {
modify(root[p], , n, x, y, type);
if(l == r) return; if(pos <= mid) ins(lc, l, mid, x, y, pos, type);
else ins(rc, mid + , r, x, y, pos, type);
} int getKth(int p, int l, int r, int x, int k) {
if(l == r) return l;
int now = query(root[lc], , n, x);
if(k <= now) return getKth(lc, l, mid, x, k);
else return getKth(rc, mid + , r, x, k - now);
} } using namespace OutSegT; int main() {
read(n), read(m), read(qn);
for(int x, y, i = ; i < n; i++) {
read(x), read(y);
add(x, y), add(y, x);
}
dfs(, , ); for(int x, y, v, i = ; i <= m; i++) {
read(x), read(y), read(v);
num[++mx] = v;
if(dep[x] > dep[y]) swap(x, y);
if(st[x] <= st[y] && ed[x] >= ed[y]) {
int z = getPos(y, dep[y] - dep[x] - );
if(ed[z] < n) {
addLine(st[y], ed[y], ed[z], n, v);
addLine(ed[z], n, st[y], ed[y], v);
}
if(st[z] > ) {
addLine(st[y], ed[y], , st[z] - , v);
addLine(, st[z] - , st[y], ed[y], v);
}
} else {
addLine(st[x], ed[x], st[y], ed[y], v);
addLine(st[y], ed[y], st[x], ed[x], v);
}
} sort(num + , num + mx + );
mx = unique(num + , num + + mx) - num - ;
for(int i = ; i <= lcnt; i++)
a[i].v = lower_bound(num + , num + mx + , a[i].v) - num; for(int i = ; i <= qn; i++) {
read(q[i].x), read(q[i].y), read(q[i].k);
q[i].x = st[q[i].x], q[i].y = st[q[i].y];
q[i].id = i;
} sort(q + , q + + qn);
sort(a + , a + + lcnt);
for(int j = , i = ; i <= qn; i++) {
for(; j <= lcnt && a[j].pos <= q[i].x; ++j)
ins(, , mx, a[j].x, a[j].y, a[j].v, a[j].type);
ans[q[i].id] = getKth(, , mx, q[i].y, q[i].k);
} for(int i = ; i <= qn; i++)
printf("%d\n", num[ans[i]]); return ;
}

Luogu 3242 [HNOI2015]接水果的更多相关文章

  1. luogu P3242 [HNOI2015]接水果

    传送门 其实这题难点在于处理路径包含关系 先求出树的dfn序,现在假设路径\(xy\)包含\(uv(dfn_x<dfn_y,dfn_u<dfn_v)\) 如果\(lca(u,v)!=u\) ...

  2. BZOJ4009: [HNOI2015]接水果

    4009: [HNOI2015]接水果 Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果. 由于她已经DT FC 了The big black,  她 ...

  3. BZOJ 4009: [HNOI2015]接水果

    4009: [HNOI2015]接水果 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 636  Solved: 300[Submit][Status] ...

  4. [BZOJ4009][HNOI2015]接水果(整体二分)

    [HNOI2015]接水果 时间限制:60s      空间限制:512MB 题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果. 由于她已经DT FC 了The b ...

  5. 洛谷 P3242 [HNOI2015]接水果 解题报告

    P3242 [HNOI2015]接水果 题目描述 风见幽香非常喜欢玩一个叫做 \(osu!\) 的游戏,其中她最喜欢玩的模式就是接水果.由于她已经\(DT\) \(FC\) 了\(\tt{The\ b ...

  6. [洛谷P3242] [HNOI2015]接水果

    洛谷题目链接:[HNOI2015]接水果 题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, 她觉得这个游戏太简 ...

  7. 【BZOJ4009】[HNOI2015]接水果 DFS序+整体二分+扫描线+树状数组

    [BZOJ4009][HNOI2015]接水果 Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, ...

  8. [HNOI2015]接水果[整体二分]

    [HNOI2015]接水果 给出一个树上路径集合\(S\) 多次询问\(x,y\)中的\(k\)小值 如果你问我数列上那么我会 树上的话 树上差分了吧直接?- 令 \(st_x<st_y\) 1 ...

  9. BZOJ4009 & 洛谷3242 & LOJ2113:[HNOI2015]接水果——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4009 https://www.luogu.org/problemnew/show/P3242 ht ...

随机推荐

  1. vue前端开发那些事——后端接口.net core web api

    红花还得绿叶陪衬.vue前端开发离不开数据,这数据正来源于请求web api.为什么采用.net core web api呢?因为考虑到跨平台部署的问题.即使眼下部署到window平台,那以后也可以部 ...

  2. ubuntn 配置webpy nginx

    webpy环境搭建 在开始webpy搭建之前,有必要熟悉一下什么是fastcgi,因为搭建环境时都是使用这个模式去运行webpy程序的,具体的fastcgi描述可以参考各种百科:fastcgi协议官网 ...

  3. python的正则re模块

    一. python的正则 python的正则模块re,是其内置模块,可以直接导入,即import re.python的正则和其他应用的正则及其相似,有其他基础的话,学起来还是比较简单的. 二. 正则前 ...

  4. javascript:;与javascript:void(0)

    如果想做一个链接点击后不做任何事情,或者响应点击而完成其他事情,可以设置其属性 href = "#",但是,这样会有一个问题,就是当页面有滚动条时,点击后会返回到页面顶端,用户体验 ...

  5. 《大教堂和集市》笔记——为什么一个本科生业余作品却成了全世界最流行的操作系统之一Linux?

    1. Eric Raymond有一篇著名文章<大教堂和集市>(The Cathedral and the Bazaar). 他说,世界上的建筑可以分两种:一种是集市,天天开放在那里,从无到 ...

  6. zookeeper运维(转)

    本文以ZooKeeper3.4.3版本的官方指南为基础:http://zookeeper.apache.org/doc/r3.4.3/zookeeperAdmin.html,补充一些作者运维实践中的要 ...

  7. cors,跨域资源共享,Java配置

    一.概念 1. 如果两个页面的协议.域名和端口是完全相同的,那么它们就是同源的,不同则为跨域 2. ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允 ...

  8. AngularJS:template2

    ylbtech-AngularJS: 1.返回顶部 1.   2. 2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部 1.   2.  6.返回顶部   作者:ylbtech出处:h ...

  9. 010. windows10下安装kivy 1.9.1版

    Microsoft Windows [版本 10.0.14393] 以管理员权限打开cmd (c) 2016 Microsoft Corporation. 保留所有权利. 1. C:\Users\LG ...

  10. (转)编写 DockerFile

    这几天在研究怎样制作docker image. 其中使用dockerfile是一种可记录制作image的过程的并且是容易重复使用的一种方式.在园子里看到了一篇好文,于是分享到这里~~ 原文链接: ht ...