湖南集訓 談笑風生

2022-05-09 10:27:09 字數 1547 閱讀 8507

嘟嘟嘟

這題剛開始猶豫了一會兒,以為「高明」的優先順序大於「談笑風生」,不過樣例表明只要兩點間距離不超過\(x\),兩人就算」談笑風生「。

接下來看看怎麼回答詢問。

首先\(a\)是固定的,且\(a,b\)都是\(c\)的祖先。那就得分類討論:

1.\(b\)是\(a\)的祖先,那麼\(c\)就是\(a\)的子樹中的所有點,根據乘法原理,三元組個數為\((size[a] - 1) * min(deep[a], x)\)。

2.\(a\)是\(b\)的祖先。那麼對於\(a\)子樹內的每乙個\(b\),合法的\(c\)都有\(b\)的子樹大小個,所以這種情況三元組個數為\(\sum _ size[b] - 1\)。至於怎麼求這些合法的\(b\),顯然就是基於\(dfs\)序的主席樹啦。

#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;

#define enter puts("")

#define space putchar(' ')

#define mem(a, x) memset(a, x, sizeof(a))

#define in inline

typedef long long ll;

typedef double db;

const int inf = 0x3f3f3f3f;

const db eps = 1e-8;

const int maxn = 3e5 + 5;

in ll read()

in void write(ll x)

in void myfile()

int n, m;

struct edge

e[maxn << 1];

int head[maxn], ecnt = -1;

in void addedge(int x, int y)

; head[x] = ecnt;

}struct tree

t[maxn * 40];

int root[maxn], tcnt = 0;

in void insert(int old, int& now, int l, int r, int val, int d)

in ll query(int old, int now, int l, int r, int id)

int dep[maxn], siz[maxn], dfn[maxn], pos[maxn], cnt = 0;

in void dfs(int now, int _f)

}int main()

dfs(1, 0);

for(int i = 1; i <= cnt; ++i) insert(root[i - 1], root[i], 1, n, dep[pos[i]], siz[pos[i]] - 1);

for(int i = 1; i <= m; ++i)

return 0;

}

luogu 3899 湖南集訓 談笑風生

題意 這題意太草了就不描述了,有黑眼鏡框和 暗示真惡毒啊 sol 對於固定的a來說,每個b的貢獻是min siza siz b 1 min siz a,siz b 1 min si za sizb 1 考慮a是b的祖先和b是a的祖先兩種情況 把min去掉 1.對於b是a的祖先,明顯答案是min de...

P3899 湖南集訓 談笑風生

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

P3899 湖南集訓 談笑風生

題目大意 n個節點的樹,q次查詢,每次查詢給出a,k求三元組的數量 a,b,c a,b,c 的定義為 a b均為c的祖先且距離 k 離線,啟發式合併線段樹,長鏈剖分當然都能過這題 這裡講講主席樹的做法 dfs序建樹 a為b的祖先時 查詢a子樹內深度 dep a k的節點的子樹和 b為a祖先時 乘法原...