portal
這題真的好.
看到樹上路徑, 腦子裡就要點分治
這一題對於每個點都要計算一遍, 如果暴算實在不好算, 這樣我們就可以考慮算貢獻.
直接計算每種顏色的貢獻.
因為一條過重心的路徑中, 可能兩邊都會有相同顏色, 那麼我們就只考慮當前點到分治中心的鏈上.
然後把多算的這條鏈上的東西刪除就可以了.
copy from here
那麼我們就可以這樣做了:1.對樹進行第一遍dfs,預處理size和上方性質中的貢獻。(開乙個color陣列即可記錄貢獻),同時記錄貢獻總和sum
2.列舉跟的所有子樹,先把子樹掃一遍清除其在color陣列中的所有貢獻。接著,對於該子樹中的每乙個點j:
設x=sigma color[j 到根上(不包括根)的所有顏色] 由於這些顏色已經出現過,我們不能在該子樹外計算其貢獻)
設num為j到根上(不包括根)的顏色數
設y為size[root]-size[該子樹](即所有其他子樹+根的點數)
則ans[j]+=sum-x+num*y;
3.別忘了計算單獨root的ans
ans[root]+=sum-color[根的顏色]+size[root]
4.清空貢獻陣列以及其他東西
#includeusing namespace std;
#define rep(i, a, b) for(int i = (a), i##_end_ = (b); i <= i##_end_; ++i)
#define drep(i, a, b) for(int i = (a), i##_end_ = (b); i >= i##_end_; --i)
#define clar(a, b) memset((a), (b), sizeof(a))
#define debug(...) fprintf(stderr, __va_args__)
typedef long long ll;
typedef long double ld;
int read()
void write(int x)
const int maxn = 100009;
struct edge g[maxn << 1];
int n, a[maxn], head[maxn], e;
void add(int u, int v) , head[u] = e;
}void init()
}ll ans[maxn], vis[maxn], tmp, heart;
int size[maxn];
void dfs(int u, int pa) }}
void centroid(int u, int pa, int field)
} if (bbs < tmp) tmp = bbs, heart = u;
}ll color[maxn], sum, cnt[maxn], size1[maxn];
void dfs_init(int u, int pa)
} if (cnt[a[u]] == 1)
--cnt[a[u]];
}void change(int u, int pa, int delta)
if (cnt[a[u]] == 1)
--cnt[a[u]];
}void count(int u, int pa, int x, int y, int num)
ans[u] += sum - x + num * y;
for (int i = head[u]; ~i; i = g[i].nxt)
--cnt[a[u]];
}void dfs_clear(int u, int pa)
}void calc(int u)
} dfs_clear(u, 0), sum = 0;
}void divconquer(int u)
}void solve()
int main()
Luogu P2664 樹上遊戲
lrb 有一棵樹,樹的每個節點有個顏色。給乙個長度為 n 的顏色序列,定義 s i,j 為 i 到 j 的顏色數量。以及 sum i sum n s i,j 現在他想讓你求出所有的 sum i 第一行為乙個整數 n 表示樹節點的數量 第二行為 n 個整數,分別表示 n 個節點的顏色 c 1 c 2 ...
P2664 樹上遊戲
分析 點分治。首先關於答案的統計轉化成計算每個顏色的貢獻。1 計算從根出發的路徑的答案 如果某乙個顏色是從根到這個點的鏈上的第一次出現的,那麼這個顏色會對根產生siz x 個貢獻。根連向它子樹的任意乙個點的路徑都包含這個顏色 2 計算子樹內每個點過根的路徑答案 記錄乙個陣列sum i 表示從根出發包...
P2664 樹上遊戲
題面 作為一道經典的點分治題目,此題能很好的考察對點分治的運用。個人認為點分治的本質在於 對於樹上近乎n2 的路徑詢問,通過有效的 劃分,使之能在穩定的時間內通過儲存資訊 獲取資訊的經典方式來求 出答案。由此看出點分治的關鍵在於儲存資訊與獲取資訊的方式。點分治的模板套上之後我們只需要考慮的是子樹與子...