【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组
题目描述
输入
第一行三个数 n和P 和Q,表示树的大小和盘子的个数和水果的个数。
输出
对于每个果子,输出一行表示选择的盘子的权值。
样例输入
10 10 10
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
3 2 217394434
10 7 13022269
6 7 283254485
6 8 333042360
4 6 442139372
8 3 225045590
10 4 922205209
10 8 808296330
9 2 486331361
4 9 551176338
1 8 5
3 8 3
3 8 4
1 8 3
4 8 1
2 3 1
2 3 1
2 3 1
2 4 1
1 4 1
样例输出
442139372
333042360
442139372
283254485
283254485
217394434
217394434
217394434
217394434
217394434
题解
DFS序+树上倍增+整体二分+树状数组
咦这不是 Highways 那道题吗?只不过是变成一条路径包含的给定路径,求第k小。
那么按照那道题的方法,要求的就是包含询问点(包含其它路径的路径,询问路径)的给定矩形(被包含的路径,给定路径)中权值第k小的。
可以想到整体二分,统计一个点在多少个权值在$[l,mid]$范围内的矩形中出现过。可以使用离线+树状数组解决。
时间复杂度$O(n\log^2n)$
然而我的代码完全不可读。。。就别看了。。。
#include <cstdio>
#include <algorithm>
#define N 40010
using namespace std;
struct data
{int x , y , z , v , w;data() {}data(int a , int b , int c , int d , int e) {x = a , y = b , z = c , v = d , w = e;}bool operator<(const data &a)const {return x < a.x;}
}a[N * 3] , q[N * 2] , t[N * 2];
int n , head[N] , to[N << 1] , next[N << 1] , cnt , fa[N][20] , deep[N] , log[N] , pos[N] , last[N] , tp , tot , f[N] , val[N] , cc[N] , ans[N];
bool cmp(const data &a , const data &b)
{return a.v < b.v;
}
inline void add(int x , int y)
{to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
}
void dfs(int x)
{int i;pos[x] = ++tp;for(i = 1 ; (1 << i) <= deep[x] ; i ++ ) fa[x][i] = fa[fa[x][i - 1]][i - 1];for(i = head[x] ; i ; i = next[i])if(to[i] != fa[x][0])fa[to[i]][0] = x , deep[to[i]] = deep[x] + 1 , dfs(to[i]);last[x] = tp;
}
int find(int x , int y)
{int i;for(i = log[y] ; ~i ; i -- )if((1 << i) <= y)x = fa[x][i] , y -= (1 << i);return x;
}
inline void update(int x , int a)
{int i;for(i = x ; i <= n ; i += i & -i) f[i] += a;
}
inline int query(int x)
{int i , ans = 0;for(i = x ; i ; i -= i & -i) ans += f[i];return ans;
}
void solve(int b , int e , int l , int r , int L , int R)
{if(b > e) return;int i;if(L == R){for(i = b ; i <= e ; i ++ ) ans[q[i].z] = L;return;}int MID = (L + R) >> 1 , mid = l - 1 , p = l;for(i = b ; i <= e ; i ++ ) cc[q[i].z] = 0;sort(a + l , a + r + 1 , cmp);while(mid < r && a[mid + 1].v <= MID) mid ++ ;sort(a + l , a + mid + 1);for(i = b ; i <= e ; i ++ ){while(p <= mid && a[p].x <= q[i].x) update(a[p].y , a[p].w) , update(a[p].z + 1 , -a[p].w) , p ++ ;cc[q[i].z] += query(q[i].y);}while(p > l) p -- , update(a[p].y , -a[p].w) , update(a[p].z + 1 , a[p].w);for(p = i = b ; i <= e ; i ++ ) if(val[q[i].z] <= cc[q[i].z]) t[p ++ ] = q[i];for(p = i = e ; i >= b ; i -- ) if(val[q[i].z] > cc[q[i].z]) t[p -- ] = q[i];for(i = b ; i <= e ; i ++ ){if(~cc[q[i].z] && val[q[i].z] > cc[q[i].z]) val[q[i].z] -= cc[q[i].z] , cc[q[i].z] = -1;q[i] = t[i];}solve(b , p , l , mid , L , MID) , solve(p + 1 , e , mid + 1 , r , MID + 1 , R);
}
int main()
{int m , k , i , x , y , z , t;scanf("%d%d%d" , &n , &m , &k);for(i = 2 ; i <= n ; i ++ ) scanf("%d%d" , &x , &y) , add(x , y) , add(y , x) , log[i] = log[i >> 1] + 1;dfs(1);for(i = 1 ; i <= m ; i ++ ){scanf("%d%d%d" , &x , &y , &z);if(deep[x] > deep[y]) swap(x , y);if(deep[x] < deep[y] && fa[t = find(y , deep[y] - deep[x] - 1)][0] == x){a[++tot] = data(1 , pos[y] , last[y] , z , 1);a[++tot] = data(pos[t] , pos[y] , last[y] , z , -1);a[++tot] = data(last[t] + 1 , pos[y] , last[y] , z , 1);}else a[++tot] = data(pos[x] , pos[y] , last[y] , z , 1) , a[++tot] = data(last[x] + 1 , pos[y] , last[y] , z , -1);}for(i = 1 ; i <= k ; i ++ ) scanf("%d%d%d" , &x , &y , &val[i]) , q[i] = data(pos[x] , pos[y] , i , 0 , 0) , q[i + k] = data(pos[y] , pos[x] , i , 0 , 0);sort(q + 1 , q + k * 2 + 1) , solve(1 , k * 2 , 1 , tot , 1 , 1000000000);for(i = 1 ; i <= k ; i ++ ) printf("%d\n" , ans[i]);return 0;
}
转载于:https://www.cnblogs.com/GXZlegend/p/7725576.html
【bzoj4009】[HNOI2015]接水果 DFS序+树上倍增+整体二分+树状数组相关推荐
- POJ2182 Lost Cows(树状数组、二分、倍增)
Lost Cows 题目链接 Description N (2 <= N <= 8,000) cows have unique brands in the range 1-N. In a ...
- 【HNOI2015】接水果【整体二分】【DFS序】【双区间转矩形】【扫描线】【树状数组】
传送门 题意:给定一个nnn个点的树,定义一个"盘子"为一个给定权值的路径,一个"水果"为一条路径,一个盘子可以接到水果当且仅当盘子的路径是水果的子路径.给出所 ...
- [HNOI2015] 接水果(倍增 + 整体二分)
problem luogu-P3242 solution 本题的难点在于如何判定路径之间是否覆盖. 这里我们尝试树常见的 dfs\text{dfs}dfs 序. 考虑 x−yx-yx−y 路径如果要覆 ...
- bzoj4009: [HNOI2015]接水果(整体二分)
题目描述 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更加难的版本. 首先有 ...
- HDU 6203 ping ping ping (在线倍增lca+DFS序+树状数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 #include<bits/stdc++.h> using namespace st ...
- 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组
[BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...
- CF-547E(Mike and Friends)后缀数组+线段树 AC自动机+DFS序+树状数组
题目链接 题意 NNN个串,每次询问区间[L,R][L,R][L,R]中有多少子串SiS_iSi 思路 把NNN个串合成一个长字符串,对这个长字符串求后缀数组,包含SiS_iSi的子串的heigh ...
- bzoj 2434 [Noi2011]阿狸的打字机(AC自动机+fail树+dfs序+树状数组)
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 3521 Solved: 1913 [Submit][S ...
- 【BZOJ3653】谈笑风生 离线+树状数组+DFS序
[BZOJ3653]谈笑风生 Description 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称"a比b不知道高明到哪里去了&quo ...
最新文章
- oracle多次发运,Oracle EBS 关于发运收集整理
- 提高开发效率之安卓模板(上面有四种模板的教程,我之前会两种,看完之后还是只会两种2333)
- directx 9.27.1734 多语言完整版 下载
- IMP出现的ORA-01401错误可能和字符集有关(转载)
- js函数引用、函数调用与回调函数
- Java RMI之介绍
- C compiler test failed.
- 机器学习 流式特征_Web服务与实时机器学习端点的流式传输
- SM2258XT+B17A测试(焊接+开卡+测速+跑圈)
- Unity 讯飞实时语音转写(三)—— 分析转写结果
- jclasslib 插件安装及使用
- Chaotica for Mac(分形艺术作品创作工具)
- 基于原理图法的全加器设计
- 复旦大学数学学院 17 级本科生对每周一题的评价
- Internet Exploer 无法打开Internet站点、、、、已终止操作
- win7或者win10碰到需要administrator权限才能删除的解决办法
- 面试必问 K8S 的经典题目,来看看你会几个?
- nova青春版支持鸿蒙吗,华为nova青春版有NFC吗 华为nova青春版支持NFC功能吗
- 可视门铃竟然可以泄露WiFi密码
- 迅睿CMS 程序安装教程
热门文章
- 如何设置并使用 Synology NAS 共享的多功能打印机
- angularjs教程网址
- .NET(C#):浅谈程序集清单资源和RESX资源
- Maven把一个Application转换成WebProject
- __user_initial_stackheap 库函数翻译(转)
- debian linux 安装smb 配置
- 关于linux内核无法编译成模块的解决方法
- instanceof java list_Java:Instanceof和泛型
- none是不是python的保留字_Python主要保留字
- 华为HCIE实验考试险过,考试真题分享、答题经验分享