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. 5,基于关系和超链接的 API

    Tutorial 5: Relationships & Hyperlinked APIs At the moment relationships within our API are repr ...

  2. js 获取 本周、上周、本月、上月、本季度、上季度的开始结束日期

    js 获取 本周.上周.本月.上月.本季度.上季度的开始结束日期 /**  * 获取本周.本季度.本月.上月的开始日期.结束日期  */ var now = new Date(); //当前日期 va ...

  3. RESTful 服务示例

    WCF服务轻量级服务,可供JS调用 返回值格式:XML.Json 工程结构: 示例代码: using System; using System.Collections.Generic; using S ...

  4. LeetCode Degree of an Array

    原题链接在这里:https://leetcode.com/problems/degree-of-an-array/description/ 题目: Given a non-empty array of ...

  5. fpga产生伪随机序列

    1,一位模二加法法则:加减法等同于异或,没有进位. 2,将移位寄存器的某几级作为抽头进行模二加法后作为反馈输入,就构成了有反馈的动态移位寄存器.此方法产生的序列是有周期的. 3,假设移位寄存器的级数为 ...

  6. 【ftp】服务器的链接命令

    1. 连接ftp服务器 格式:ftp [hostname| ip-address] a)在Linux命令行下输入: ftp 192.168.1.1 b)服务器询问你用户名和密码,分别输入用户名和相应密 ...

  7. qt的下载地址

    上Qt官网http://www.qt.io/download/想下载Qt,速度很慢,在这里记录下在Qt官网看到的镜像下载地址: 1. 所有Qt版本下载地址: http://download.qt.io ...

  8. Erlang基础 -- 介绍 -- 历史及Erlang并发

    前言 最近在总结一些Erlang编程语言的基础知识,拟系统的介绍Erlang编程语言,从基础到进阶,然后再做Erlang编程语言有意思的库的分析. 其实,还是希望越来越多的人关注Erlang,使用Er ...

  9. laravel安装初体验

    1.github下载laravel 2.通过composer安装相应的库 composer config repo.packagist composer https://packagist.phpco ...

  10. thinkphp线上自动加载异常与修复

    项目遇到一个奇怪的问题,本地代码正常,服务器上却不正常. 经过测试,应该是自动加载出了问题,尝试了各种方法, 1.手动加载,发现好麻烦,没完没了. 2.自己写自动加载,写不出来,尴尬. 3.修改配置, ...