P3899 湖南集訓 談笑風生

2022-05-20 20:46:03 字數 1242 閱讀 9148

題目大意

n個節點的樹,q次查詢,每次查詢給出a,k求三元組的數量(a,b,c),(a,b,c)的定義為:a、b均為c的祖先且距離<=k

離線,啟發式合併線段樹,長鏈剖分當然都能過這題

這裡講講主席樹的做法

dfs序建樹

a為b的祖先時 查詢a子樹內深度<=dep[a]+k的節點的子樹和

b為a祖先時 乘法原理就好

my complete code:

#include#include#include#includeusing namespace std;

typedef long long ll;

const ll maxn=3e5+5;

const ll inf=1e18;

inline ll read()

while(c>='0'&&c<='9')

return x*f;

}struct nodedis[maxn<<1];

ll num,cnt,n,q,nod;

ll head[maxn],dfn[maxn],low[maxn],root[maxn],a[maxn],b[maxn],dep[maxn],size[maxn];

ll rt[maxn<<7],lt[maxn<<7],sum[maxn<<7],date[maxn<<7];

inline void add(ll u,ll v); head[u]=num;

}void dfs(ll u,ll fa)

low[u]=num;

}void update(ll &now,ll pre,ll l,ll r,ll c,ll u)

if(c<=mid)else

sum[now]=sum[lt[now]]+sum[rt[now]];

}ll query(ll pre,ll next,ll l,ll r,ll c)

int main()

num=0;

dfs(1,0);

cnt=n;

b[++cnt]=inf;

sort(b+1,b+1+cnt);

cnt=unique(b+1,b+1+cnt)-b-1;

for(ll i=1;i<=n;++i)

--size[i];

for(ll i=1;i<=n;++i)

while(q--)

return 0;

}

P3899 湖南集訓 談笑風生

傳送門 首先 a,b,c 肯定在一條鏈上。當 b 為 a 的祖先時,a 的子樹中所有與它不同的點都可以作為點 c 當 a 為 b 的祖先時,b 的子樹中所有與它不同的點都可以作為答案 我會說我以前根本沒寫過線段樹合併結果完全不知道錯在 麼 luogu judger enable o2 minamot...

洛谷 P3899 湖南集訓 談笑風生

原題鏈結 題目大意 有一棵 n nn 個節點的有根樹,有 m mm 組詢問 每次詢問給出 a,k a,ka,k,求有多少個三元組 a,b,c a,b,c a,b,c 滿足 a,b a,ba,b 都是 c cc 的祖先,並且 a,b a,ba,b 之間的距離不超過 kkk 剛開始沒有思路,看了題解的分...

洛谷P3899 湖南集訓 談笑風生

設t 為一棵有根樹,我們做如下的定義 設a和b為t 中的兩個不同節點。如果a是b的祖先,那麼稱 a比b不知道 高明到 去了 設a 和 b 為 t 中的兩個不同節點。如果 a 與 b 在樹上的距離不超過某個給定 常數x,那麼稱 a 與b 談笑風生 給定一棵n個節點的有根樹t,節點的編號為1 到 n,根...