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. BAT脚本编写要点_特殊字符

    BAT脚本编写要点(1)_特殊字符 分类: 其他 2011-03-20 00:58 5621人阅读 评论(0) 收藏 举报 脚本cdatecmdtreesystem 1. 点 与echo连用,作用是换 ...

  2. 自定义vue组件之仿百度分页逻辑

    <template> <div> <ul :total="total" :pageSize="pageSize" :pageNum ...

  3. 选择IT行业的自我心得,希望能帮助到各位!(一)

    我记得当时我还在读书的时候,也是卡在高三在后面,纠结我该怎么选择专业,一边顶着高考的压力又担心这担心那的,前怕狼后怕虎,一直犹犹豫豫,知道有一天我就听到谁谁谁的哥哥学IT老牛逼了,一个月多少多少钱,买 ...

  4. python脚本如何同时运行多个

    当我们想一次运行多个py脚本的时候你想到了什么应用场景了吗?当你想同时并行的处理一些对象时你有什么好方法吗?下面我就简单的总结一些这方面的小技巧,方便大家根据情况灵活处理. 1 用一个py脚本运行多个 ...

  5. Linux安装PHP的Redis扩展(已安装Redis)

    1.下载需要的php操作redis的扩展包 下载地址 http://pecl.php.net/package/redis    下载对应php版本,我的php版本为7.3,下载的是最新的版本5.0.2 ...

  6. net core天马行空系列:降低net core门槛,数据库操作和http访问仅需写接口,实现类由框架动态生成

    引文   hi,大家好,我是三合.不知各位有没有想过,如果能把数据库操作和http访问都统一封装成接口(interface)的形式, 然后接口对应的实现类由框架去自动生成,那么必然能大大降低工作量,因 ...

  7. 实战 | 将Apache Hudi数据集写入阿里云OSS

    1. 引入 云上对象存储的廉价让不少公司将其作为主要的存储方案,而Hudi作为数据湖解决方案,支持对象存储也是必不可少.之前AWS EMR已经内置集成Hudi,也意味着可以在S3上无缝使用Hudi.当 ...

  8. TensorFlow的模型保存与加载

    import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import tensorflow as tf #tensorboard --logdir=&qu ...

  9. Java IO 流 -- 设计模式:装饰设计模式

    在java IO 流中我们经常看到这样的写法: ObjectOutputStream oos = new ObjectOutputStream( new BufferedOutputStream(ne ...

  10. C#客户端打印条形码

    第一种方法: 引用第三方插件文件zxing.dll // 1.设置条形码规格 EncodingOptions encodeOption = new EncodingOptions(); encodeO ...