hdu 3887 樹狀陣列(模擬棧)

2022-05-24 10:51:07 字數 1535 閱讀 6072

一棵樹,求每個結點的子樹中有幾個數是小於這個數的

dfs會進入乙個點一次,出乙個點一次,中間經過的點都是它的子樹中的點,所以,進入的時候統計一遍,出來的時候統計一遍,兩個結果相減就可以了

純dfs會爆棧,要模擬棧。

不過,不模擬棧也可以過,在網上看到c++可以設定棧的大小,所以把棧空間設定的大一點直接dfs做就可以了

view code

#pragma comment(linker,"/stack:100000000,100000000")

#include

#include

const

int maxn = 100010;

struct edgeedge[maxn*2];

int head[maxn],ans[maxn],p[maxn];

int tot;

void add(int a,int b)

int c[maxn];

int lowbit(int x)

void update(int x,int d)

void dfs(int x,int fa)

}ans[x]=sum(x-1)-p[x];

}int main()

dfs(root,root);

for(i=1;i"

%d ",ans[i]);

printf("

%d\n

",ans[n]);

}return

0;}

當然,模擬棧是通用做法,一定要學會

view code

#include

#include

#include

using

namespace std;

stack ss;

const

int maxn = 100010;

struct edgeedge[maxn*2];

int head[maxn],ans[maxn],l[maxn],r[maxn],seq[maxn*2],re[maxn],c[maxn*2];

bool vis[maxn];

int tot;

void add(int a,int b)

int lowbit(int x)

void update(int x,int d)

int sum(int x)

void dfs(int root)

bool flag=false;

for(int i=re[now];i!=-1;i=edge[i].next)

}if(flag) continue;

if(vis[now])}}

void solve(int n)

}int main()

dfs(root);

solve(n);

for(i=1;i"

%d ",ans[i]);

printf("

%d\n

",ans[n]);

}return

0;}

hdu 3887 樹狀陣列

給你一棵樹,每個節點都有個編號。讓你求乙個節點他的子樹中編號比他小的節點有幾個。編號唯一,從1 n,已給出根節點 解 樹狀陣列統計。轉化為線性序列。可以想到的是,若要統計乙個節點,那麼比它小的孩子必須先插完,然後統計就行了。對於乙個節點i來說,只要把所有x那麼對於所有節點來說也是這樣的,從一開始插,...

hdu3887dfs序 樹狀陣列 線段樹

題目 大意 求在當前點的所有後代中,後代點的序號大小 當前點的序號大小,並統計他們的個數,這就是f i 思路 dfs序 樹狀陣列 線段樹 dfs序 dfs序 dfs是深度優先的,所以對於乙個點,它會先遍歷完它的所有子節點,再去遍歷他的兄弟節點以及其他所以對於一棵樹的dfs序來說,這個點和他所有的子節...

bzoj 1106 貪心 樹狀陣列 或 棧模擬

題意 n個數,各出現兩次,當兩個相同的數相鄰時,這兩個數同時消除,上方的方塊同時下落且可繼續消除滿足條件的。每次可交換相鄰的兩個方塊,求最少交換次數使得所有數全消除 首先,對於一對相同的數中間有另一對的情況 即兩對相同的數是巢狀關係 肯定要先消除另一對 其次,對於一對相同的數中間有另一對中的乙個的情...