http://www.lydsy.com/JudgeOnline/problem.php?id=3648
http://hi.baidu.com/greencloud/item/5d009dddcecde7b133db90ad
Brief description:
给定一个树加一条边。。求这个图中所有经过结点树 >= k 的路径有多少组。。
((u -> v) 与 (v -> u) 算一组。。)
Analysis:
树的情况树分治即可。。。由于都是单位权。。。我们树状数组即可。。基本功。。。
考虑环的情况。。。比如样例。。。。
我们沿顺时针转三次。。。(注意 (u, v) 和 (v, u) 只统计一次。。而他们正好分别对应一次顺时针和一次逆时针。、、)
这里 d 是 offset。。。
//}/* .................................................................................................................................. */
const int N = int(1e5) + 9, M = N*2;
namespace BIT{
const int N = ::N+::N+1;
int C[N], n;
void Add(int x, int d = 1){
x += ::N;
for (;x<N;x+=low_bit(x)) C[x] += d;
}
int Sum(int x){
x += ::N;
int res = 0; for (;x;x^=low_bit(x)) res += C[x];
return res;
}
int Rsum(int x){
int t = Sum(::N); t -= x + ::N > 0 ? Sum(x) : 0;
return t;
}
} //using namespace BIT;
int hd[N], prd[M], suc[M], to[M];
int m;
void add_edge(int a, int b){
to[m] = b, suc[prd[hd[a]] = m] = hd[a], hd[a] = m++;
}
void add_edgee(int a, int b) {
add_edge(a, b);
add_edge(b, a);
}
#define aa to[i^1]
#define bb to[i]
#define v bb
inline void del(int i){
if (hd[aa] == i) prd[hd[aa] = suc[i]] = 0;
else prd[suc[i]] = prd[i], suc[prd[i]] = suc[i];
}
inline void rsm(int i){
if (suc[i] == hd[aa]) hd[aa] = i;
prd[suc[i]] = suc[prd[i]] = i;
}
inline void dell(int i){
del(i), del(i^1);
}
inline void rsmm(int i){
rsm(i), rsm(i^1);
}
int n, k; int sz[N], dep[N]; LL ans; VI L;
void Scann(int u, int p) {
L.PB(dep[u]); REP_G(i, u) if (v != p){
dep[v] = dep[u] + 1;
Scann(v, u);
}
}
void Scan(int u){
CLR(L); dep[u] = 1; L.PB(dep[u]);
REP_G(i, u){
dep[v] = dep[u] + 1;
Scann(v, u);
}
}
namespace TDC{
int nn, cc, c;
void dfsc(int u, int p = 0){
int ss = 0; sz[u] = 1; REP_G(i, u) if (v != p){
dfsc(v, u), sz[u] += sz[v];
checkMax(ss, sz[v]);
}
checkMax(ss, nn - sz[u]);
if (ss <= cc) cc = ss, c = u;
}
void dfs0(int u, int p = -1){
sz[u] = 1; REP_G(i, u) if (v != p){
dep[v] = dep[u] + 1;
dfs0(v, u);
sz[u] += sz[v];
}
}
void dfs1(int u, int p){
L.PB(dep[u]);
REP_G(i, u) if (v != p){
dfs1(v, u);
}
}
void dfs2(int u, int p = -1){
BIT::Add(dep[u], -1);
REP_G(i, u) if (v != p){
dfs2(v, u);
}
}
void gao(int u = 1){
cc = INF, dfsc(u), u = c;
dep[u] = 1; dfs0(u); BIT::Add(1);
REP_G(i, u){
CLR(L); dfs1(v, u);
ECH(it, L) ans += BIT::Rsum(k-*it);
ECH(it, L) BIT::Add(*it);
}
dfs2(u);
REP_G(i, u){
nn = sz[v], dell(i), gao(v), rsmm(i);
}
}
}
VI Circle; PII sta[N]; int pos[N], top = 0;
void dfs(int u = 1, int p = -1){ // Find_Circle
sta[pos[u]=++top].fi = u;
REP_G(i, u) if (i != (p^1)){
sta[top].se = i;
if (!pos[v]) dfs(v, i);
else {
FOR_1(ii, pos[v], top) {
Circle.PB(sta[ii].fi);
dell(sta[ii].se);
}
}
}
--top;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
m = 2; int m; RD(n, m, k); DO(m){
int a, b; RD(a, b);
add_edgee(a, b);
}
if (m == n-1) TDC::gao();
else {
dfs(); ECH(c, Circle) TDC::gao(*c);
int d = 0;
ECH(c, Circle){
Scan(*c);
ECH(it, L) BIT::Add(*it-d);
++d;
}
ECH(c, Circle){
Scan(*c);
ECH(it, L) BIT::Add(*it-d+SZ(Circle), -1);
ECH(it, L) ans += BIT::Rsum(k-d-*it);
ECH(it, L) BIT::Add(*it-d);
++d;
}
ECH(c, Circle){
Scan(*c);
ECH(it, L) BIT::Add(*it-d+SZ(Circle), -1);
++d;
}
}
printf("%lld\n", ans);
}




Alca
Amber
Belleve Invis
Chensiting123
Edward_mj
Fotile96
Hlworld
Kuangbin
Liyaos
Lwins
LYPenny
Mato 完整版
Mikeni2006
Mzry
Nagatsuki
Neko13
Oneplus
Rukata
Seter
Sevenkplus
Sevenzero
Shirleycrow
Vfleaking
wangzhpp
Watashi
WJMZBMR
Wywcgs
XadillaX
Yangzhe
三途川玉子
About.me
Vijos
