這個題目還是比較簡單的,但是比賽的時候沒有像清楚,用了乙個不太熟悉的資料結構主席樹,
所以出現了bug,主席樹的bug是真的難找。
這個題目就是首先用dfs+線段樹求出每乙個富翁的val
然後用二分加線段樹來找位置。
#include #includeview code#include
#include
#include
#include
#define inf 0x3f3f3f3f
using
namespace
std;
const
int maxn = 1e5 + 10
;typedef
long
long
ll;ll a[maxn], lazy[maxn * 4], sum[maxn * 4], flag[maxn * 4
];int
n, val[maxn];
vector
g[maxn];
void add(int u, int
v) void push_down(int id,int l,int
r)
if (flag[id << 1 | 1
]) lazy[id] = 0;}
void update1(int id, int l, int r, int pos,int
f) push_down(id, l, r);
int mid = (l + r) >> 1
;
if (pos <= mid) update1(id << 1
, l, mid, pos, f);
else update1(id << 1 | 1, mid + 1
, r, pos, f);
sum[id] = sum[id << 1] + sum[id << 1 | 1];}
void update2(int id,int l,int r,int x,int
y) push_down(id, l, r);
int mid = (l + r) >> 1
;
if (x <= mid) update2(id << 1
, l, mid, x, y);
if (y > mid) update2(id << 1 | 1, mid + 1
, r, x, y);
sum[id] = sum[id << 1] + sum[id << 1 | 1];}
int query(int id,int l,int r,int
pos)
void dfs(int u, int
pre)
update1(
1, 1, n, a[u], 1);}
intc[maxn];
int lowbit(int
x)void update(int x,intk)}
int getsum(int
x)
return
ans;
}int
main()
dfs(
1, -1
);
for (int i = 1; i <= n; i++) if (val[i] >= inf) val[i] = 1
;
//for (int i = 1; i <= n; i++) printf("val[%d]=%d\n", i, val[i]);
for (int i = 1; i <= n; i++)
printf(
"%d\n
", ans);
update(ans, 1);
}return0;
}
Sequence(線段樹 二分)
傳送門 第二次做這種題目,把人做傻了,沒想到是二分,只是隱隱約約感覺到了二分的影子。於是寫了兩個查詢的函式,但是發現查詢的函式無法解決求左邊最大值和右邊最小值的問題。寫了一大堆爛 正解只需要在查詢的時候不斷二分就行了。include using namespace std typedef long ...
VVQ 與線段 線段樹 二分
原題鏈結 這題主要是要去判斷2個線段會不會又交集。首先將線段按r從小到大排列,然後乙個乙個放進線段樹裡面方便以後查詢有交集的範圍內的被減數的最小值。然後求交集,若lr與lr有交集,且r是右邊的那個線段。就有l r r,這裡可以使用二分函式lower bound求,主要快一點。然後,交集又分2種情況。...
Work 線段樹 二分答案
開始也想到二分,但是無法判斷哪些天數比它大,比它小 排序啊,人按浪費的時間排序,題按時間排序,下標加入線段樹 include define n 200005 define ll long long using namespace std int m,n,ans n mid,cnt n 4 時間總和 ...