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. 重温CLR(三)类型基础

    所有类型都从System.Object派生 “运行时”要求每个类型最终都要从System.Object类型派生.也就是说,一下两个类型的定义完全一致. //隐式派生自Object class Empl ...

  2. 组件与.NET互操作

    组件 1.何谓组件技术? 组件技术就是利用某种编程手段,将一些人们所关心的,但又不便于让最终用户去直接操作的细节进行了封装,同时对各种业务逻辑规则进行了实现,用于处理用户的内部操作细节,甚至于将安全机 ...

  3. jQuery火箭图标返回顶部代码

    在网上找来段使用jQuery火箭图标返回顶部代码,感觉比较酷,比较炫,大概样式如下, 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1. ...

  4. F4NNIU 学习目录 (2018-08-22)

    F4NNIU 学习目录 语言 C 语言 C 语言程序设计进阶 在线刷题 https://leetcode-cn.com/problemset/all/ 工具 Git 版本管理 在线教程 在线教程

  5. Rancher使用入门

    http://tonybai.com/2016/04/14/an-introduction-about-rancher/

  6. android httpclient 设置超时

    3.X是这样的 HttpClient httpClient=new DefaultHttpClient();4.3是这样的CloseableHttpClient httpClient = HttpCl ...

  7. 【转】Jmeter内存溢出处理方式记录

    方法一: 使用jmeter进行压力测试时 遇到一段时间后报内存溢出outfmenmory错误,导致jmeter卡死了,先尝试在jmeter.bat中增加了JVM_ARGS="- Xmx204 ...

  8. namespace及use的用法

    namespace(以下简称ns).在定义了一个ns之后,下面所申明的class.interface.const(不包含variable)都是在申明的ns这个“域”里面的.当引用一个申明了ns的包含文 ...

  9. FusionCharts simple demo for (html+js、APS.NET Webform、MVC)

    做GIS或其他内部数据统计项目的应该对FusionCharts也不会太陌生,简单易用已无需多说什么了,只是有时候框架不同,实现起来也稍有差异 引用dll调用FusionCharts类的静态方法Rend ...

  10. mysql安装与基本管理

    一.MySQL介绍 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下公司.MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是 ...