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的更多相关文章

  1. Codeforces Gym 100803G Flipping Parentheses 线段树+二分

    Flipping Parentheses 题目连接: http://codeforces.com/gym/100803/attachments Description A string consist ...

  2. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  3. hdu4614 线段树+二分 插花

    Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N ...

  4. 洛谷P4344 脑洞治疗仪 [SHOI2015] 线段树+二分答案/分块

    !!!一道巨恶心的数据结构题,做完当场爆炸:) 首先,如果你用位运算的时候不小心<<打成>>了,你就可以像我一样陷入疯狂的死循环改半个小时 然后,如果你改出来之后忘记把陷入死循 ...

  5. CF877E Danil and a Part-time Job 线段树维护dfs序

    \(\color{#0066ff}{题目描述}\) 有一棵 n 个点的树,根结点为 1 号点,每个点的权值都是 1 或 0 共有 m 次操作,操作分为两种 get 询问一个点 x 的子树里有多少个 1 ...

  6. luogu4422 [COCI2017-2018#1] Deda[线段树二分]

    讨论帖:线段树二分的题..我还考场切过..白学 这题我一年前的模拟赛考场还切过,现在就不会了..好菜啊. 显然直接线段树拆成$\log n$个区间,然后每个区间在进行线段树二分即可. UPD:复杂度分 ...

  7. bzoj4399 魔法少女LJJ 线段树合并+线段树二分+并查集

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4399 题解 毒瘤题 \(9\) 种操作还有支持动态图的连通性 仔细读题 $ c<=7$. ...

  8. [BZOJ 2653] middle(可持久化线段树+二分答案)

    [BZOJ 2653] middle(可持久化线段树+二分答案) 题面 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序 ...

  9. 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, ...

随机推荐

  1. jetCache 基本使用

    1.pom引用 <!--jetcache缓存 lettuce--> <dependency> <groupId>com.alicp.jetcache</gro ...

  2. 条件变量 condition_variable wait

    wait(阻塞当前线程,直到条件变量被唤醒) #include <iostream> #include <string> #include <thread> #in ...

  3. [编译] 7、在Linux下搭建安卓APP的开发烧写环境(makefile版-gradle版)—— 在Linux上用命令行+VIM开发安卓APP

    April 18, 2020 6:54 AM - BEAUTIFULZZZZ 目录 0 前言 1 gradle 安装配置 1.1 卸载系统默认装的gradle 1.2 下载对应版本的二进制文件 1.3 ...

  4. split(" {1,}") 含义

    将字符串按照括号内的内容分割成字符数组 这里括号内是正则表达式,X{m,n}代表X至少重复m次,至多重复n次 这里x为空格,至少重复1次,就是将字符串以一个或多个空格分割 如"1 2 ab ...

  5. D3.js 力导向图的拖拽(drag)与缩放(zoom)

    不知道大家会不会跟我一样遇到这样的问题,在之前做的力导向图的基础上加上缩放功能的时候,拖动节点时整体会平移不再是之前酷炫的效果(失去了拉扯的感觉!).天啊,简直不能接受如此丑X的效果.经过不懈的努力终 ...

  6. 读写SQL脚本进行创建表、视图和存储过程

    一.按照先创建表.视图.存储过程的顺序创建: 二.导出脚本的时候注意:保存为ANSI文本,选项中:if not exists为true,防止覆盖:包含说明性标头为false;use database为 ...

  7. 机器学习常见面试题—支持向量机SVM

    前言 总结了2017年找实习时,在头条.腾讯.小米.搜狐.阿里等公司常见的机器学习面试题. 支持向量机SVM 关于min和max交换位置满足的 d* <= p* 的条件并不是KKT条件 Ans: ...

  8. 19.SpringCloud实战项目-SpringCloud整合Alibaba-Nacos配置中心

    SpringCloud实战项目全套学习教程连载中 PassJava 学习教程 简介 PassJava-Learning项目是PassJava(佳必过)项目的学习教程.对架构.业务.技术要点进行讲解. ...

  9. Yii2.0 rules常用验证规则

    设置一个修改方法,但是save(),没有成功,数据修改失败,查了好久,一般情况就是不符合rules规则,而我没有设置rules规则,重新设置了一个不能为空,然后就修改成功,rules里面什么也不写,也 ...

  10. 最简单的懒人springcloud之Eureka(服务注册与发现)

    本文开发软件是STS,是eclipse为springboot项目而生的一个软件,用这个软件开发spring的项目版本都会自己对应的,话不多说直接上代码 springboot版本2.1.8.RELEAS ...