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. tf.nn.depthwise_conv2d 卷积

    tf.nn.depthwise_conv2d( input, filter, strides, padding, rate=None, name=None, data_format=None ) 参数 ...

  2. 用threejs 实现3D物体在浏览器展示

    用threejs 实现3D物体在浏览器展示,通过鼠标平移,缩放,键盘箭头按钮左右移动等功能展示. <!DOCTYPE html> <html> <head> < ...

  3. 把川普射上太阳—如何用python制作小游戏

    1.准备 开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装. Windows环境下打开Cmd(开始—运行—CMD),苹果系统 ...

  4. L19深度学习中的优化问题和凸性介绍

    优化与深度学习 优化与估计 尽管优化方法可以最小化深度学习中的损失函数值,但本质上优化方法达到的目标与深度学习的目标并不相同. 优化方法目标:训练集损失函数值 深度学习目标:测试集损失函数值(泛化性) ...

  5. C - Sigma Function LightOJ - 1336 (数论)

    一个让人脑洞大开的题. 题目大意比较简单,询问[1,n]有多少个数其因子和为偶数. 因子分解定理中求因子和的公式是 f(n)=(1+p1+p1^2+p1^3+...+p1^a1)(1+p2+p2^2+ ...

  6. icepdf和pdfbox转pdf文档为图片

    icepdf转pdf文档为图片 首先导入icepdf jar包或maven pdfPath为pdf文件路径.pdfimgpsth为图片保存的路径 public static void icePdfIm ...

  7. java IO流 之 字节流与字符流

    其实学习了file文件基础类,后面的字节流和字符流都特别简单了,首先需要知道字节流和字符流的区别 字节流: 用来传送图片.各种文件.大文件.文本都是通过字节流进行传输的. 字符流: 只能读取文本信息 ...

  8. GoJS事件

    1.阻止键盘事件 myDiagram.commandHandler.doKeyDown = function () { var e = myDiagram.lastInput; // Meta(Com ...

  9. 定期清理nohup.out

    事件背景 服务应用weblogic通过nohup启动. nohup的使用全部都在weblogic域中的bin目录下 但是没有做定期nohup.out的清理 导致核心服务的日志过大,在出现问题时候难以打 ...

  10. Nginx四层代理

    Nginx支持四层代理 http://nginx.org/en/docs/stream/ngx_stream_core_module.html 该ngx_stream_core_module模块自1. ...