大富翁 线段树+二分 +dfs
https://csustacm.fun/problem/2033
这个题目还是比较简单的,但是比赛的时候没有像清楚,用了一个不太熟悉的数据结构主席树,
所以出现了bug,主席树的bug是真的难找。
这个题目就是首先用dfs+线段树求出每一个富翁的val
然后用二分加线段树来找位置。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <algorithm>
#include <iostream>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e5 + ;
typedef long long ll;
ll a[maxn], lazy[maxn * ], sum[maxn * ], flag[maxn * ];
int n, val[maxn];
vector<int>G[maxn];
void add(int u, int v) {
G[u].push_back(v);
G[v].push_back(u);
} void push_down(int id,int l,int r) {
if (lazy[id] == ) return;
// printf("ss id=%d l=%d r=%d\n", id, l, r);
int mid = (l + r) >> ;
if (flag[id << ]) {
// printf("id=%d l=%d r=%d\n", id, l, r);
sum[id << ] += (mid - l + )*lazy[id];
lazy[id << ] += lazy[id];
}
if (flag[id << | ]) {
// printf("ww id=%d l=%d r=%d\n", id, l, r);
sum[id << | ] += (r - mid)*lazy[id];
lazy[id << | ] += lazy[id];
}
lazy[id] = ;
} void update1(int id, int l, int r, int pos,int f) {
if (pos<l || pos>r) return;
if (f == ) flag[id]++;
else if (f == )flag[id]--;
if (l == r) {
sum[id] = ;
return;
}
push_down(id, l, r);
int mid = (l + r) >> ;
if (pos <= mid) update1(id << , l, mid, pos, f);
else update1(id << | , mid + , r, pos, f);
sum[id] = sum[id << ] + sum[id << | ];
} void update2(int id,int l,int r,int x,int y)
{
// printf("id=%d l=%d r=%d x=%d y=%d\n", id, l, r, x, y);
if (x > r || y < l) return;
if (x <= l && y >= r) {
lazy[id] += ;
sum[id] += (r - l + );
return;
}
push_down(id, l, r);
int mid = (l + r) >> ;
if (x <= mid) update2(id << , l, mid, x, y);
if (y > mid) update2(id << | , mid + , r, x, y);
sum[id] = sum[id << ] + sum[id << | ];
} int query(int id,int l,int r,int pos)
{
if (pos<l || pos>r) return ;
if (l == r) return sum[id];
push_down(id, l, r);
int mid = (l + r) >> ;
if (pos <= mid) return query(id << , l, mid, pos);
return query(id << | , mid + , r, pos);
} void dfs(int u, int pre) {
// printf("u=%d a=%lld\n", u, a[u]);
update2(, , n, , a[u]);
update1(, , n, a[u], );
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i];
if (v == pre) continue;
dfs(v, u);
val[a[u]] = min(val[a[u]], query(, , n, a[u]));
// printf("val[%lld]=%d v=%d\n", a[u], val[a[u]], v);
update1(, , n, a[u], );
}
update1(, , n, a[u], );
} int c[maxn]; int lowbit(int x)
{
return x & (-x);
} void update(int x,int k)
{
while (x <= n) {
c[x] += k;
x += lowbit(x);
}
} int getsum(int x)
{
int ans = ;
while (x > ) {
ans += c[x];
x -= lowbit(x);
}
return ans;
} int main() {
int x;
scanf("%d", &n);
memset(val, inf, sizeof(val));
for (int i = ; i <= n; i++) scanf("%d", &x), a[x] = i, G[i].clear();
for (int i = ; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
}
dfs(, -);
for (int i = ; i <= n; i++) if (val[i] >= inf) val[i] = ;
// for (int i = 1; i <= n; i++) printf("val[%d]=%d\n", i, val[i]);
for (int i = ; i <= n; i++) {
int l = , r = n, ans = ;
while (l <= r) {
int mid = (l + r) >> ;
int res = mid - getsum(mid);
if (res >= val[i]) ans = mid, r = mid - ;
else l = mid + ;
}
printf("%d\n", ans);
update(ans, );
}
return ;
}
大富翁 线段树+二分 +dfs的更多相关文章
- Codeforces Gym 100803G Flipping Parentheses 线段树+二分
Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...
- Codeforces Gym 100231B Intervals 线段树+二分+贪心
Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...
- hdu4614 线段树+二分 插花
Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...
- 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块
!!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...
- CF877E Danil and a Part-time Job 线段树维护dfs序
\(\color{#0066ff}{题目描述}\) 有一棵 n 个点的树,根结点为 1 号点,每个点的权值都是 1 或 0 共有 m 次操作,操作分为两种 get 询问一个点 x 的子树里有多少个 1 ...
- luogu4422 [COCI2017-2018#1] Deda[线段树二分]
讨论帖:线段树二分的题..我还考场切过..白学 这题我一年前的模拟赛考场还切过,现在就不会了..好菜啊. 显然直接线段树拆成$\log n$个区间,然后每个区间在进行线段树二分即可. UPD:复杂度分 ...
- bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...
- [BZOJ 2653] middle(可持久化线段树+二分答案)
[BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...
- Educational Codeforces Round 64 (Rated for Div. 2) (线段树二分)
题目:http://codeforces.com/contest/1156/problem/E 题意:给你1-n n个数,然后求有多少个区间[l,r] 满足 a[l]+a[r]=max([l, ...
随机推荐
- GitHub搭建个人主页
GitHub搭建个人主页 1.注册登录GitHub 2.新建仓库 新建一个名为"username.github.io",其中username为你的用户名,仓库必须为公有类型,私有仓 ...
- Flutter 吐血整理组件继承关系图
老孟导读:前几天一个读者和我说能不能整理一个各个控件之间的继承关系,这2天抽时间整理了一下,不整理不知道,一整理真的吓一跳啊,仅仅Widget的子类(包括间接子类)就高达353个,今天发群里给大家浏览 ...
- 并查集---体会以及模板&&How Many Tables - HDU 1213
定义&&概念: 啥是并查集,就是将所有有相关性的元素放在一个集合里面,整体形成一个树型结构,它支持合并操作,但却不支持删除操作 实现步骤:(1)初始化,将所有节点的父亲节点都设置为自己 ...
- Java编程最差实践常见问题详细说明(2)转
Java编程最差实践常见问题详细说明(2)转 2012-12-13 13:57:20| 分类: JAVA | 标签:java |举报|字号 订阅 反射使用不当 错误的写法: Java代 ...
- web.xml被文件加载过程,各节点加载顺序总结
web.xml被文件加载过程,各节点加载顺序总结 博客分类: J2EE WebXMLSpringServletBean 今天2010-3-11日,上班无事,想来将web.xml项目描述文件的加载过程 ...
- MAC 上brew 更新 出错
在MAC上brew update的时候出现报错:Error: /usr/local must be writable! 错误,在该文章中也给出解决办法(sudo chown -R $(whoami) ...
- 别人用钱,而我用python爬虫爬取了一年的4K高清壁纸
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取htt ...
- 8行代码帮你python建立UDP通信
首先我们要搭建一个UDP通信,首先我们就要知道什么UDP: UDP用户数据报传输协议,它位于TCP/IP协议的传输层,是一种无连接的协议,它发送的报文不能确定是否完整地到达了另外一端.UDP广泛应用于 ...
- L8梯度消失、梯度爆炸
houseprices数据下载: 链接:https://pan.baidu.com/s/1-szkkAALzzJJmCLlJ1aXGQ 提取码:9n9k 梯度消失.梯度爆炸以及Kaggle房价预测 代 ...
- [转载]绕过CDN查找真实IP方法总结
前言 类似备忘录形式记录一下,这里结合了几篇绕过CDN寻找真实IP的文章,总结一下绕过CDN查找真实的IP的方法 介绍 CDN的全称是Content Delivery Network,即内容分发网络. ...