嘟嘟嘟
這題剛開始猶豫了一會兒,以為「高明」的優先順序大於「談笑風生」,不過樣例表明只要兩點間距離不超過\(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祖先時 乘法原...