生活随笔
收集整理的這篇文章主要介紹了
Dominant Indices(CF 1009 F)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言
記錄一下長鏈剖分的小技巧
題目相關
鏈接
題目大意
一棵nnn個節點的樹,定義fi,jf_{i,j}fi,j?為與iii號點距離為jjj的節點數量,對于每個iii求出一個最小的jjj滿足fi,jf_{i,j}fi,j?是所有jjj的取值中最大的
數據范圍
n≤106n\le10^6n≤106
題解
直接長鏈剖分即可,我們發現“重”兒子繼承的時候是直接最前面加個1,所以可O(1)\mathcal O(1)O(1)繼承,“輕”兒子合并直接暴力,復雜度是O(len)\mathcal O(len)O(len)的(lenlenlen為“輕”兒子所在長鏈的長度)
我們發現復雜度是sigma長鏈長度的,所以算法總復雜度為O(n)\mathcal O(n)O(n)
代碼
實際實現的時候有些細節和技巧
這里貼一下代碼中變量的解釋
D[u].sz[i]表示當前點u子樹內距離為len[u]-i-1的點的數量
然后D[u].maxx和D[u].pl分別代表最大值和最大值的位置
這樣就能方便的合并了
#include<bits/stdc++.h>
using namespace std
;
typedef long long ll
;
#define rg register
template
<typename T
> inline void read(T
&x
){char cu
=getchar();x
=0;bool fla
=0;while(!isdigit(cu
)){if(cu
=='-')fla
=1;cu
=getchar();}while(isdigit(cu
))x
=x
*10+cu
-'0',cu
=getchar();if(fla
)x
=-x
;}
template
<typename T
> inline void printe(const T x
){if(x
>=10)printe(x
/10);putchar(x
%10+'0');}
template
<typename T
> inline void print(const T x
){if(x
<0)putchar('-'),printe(-x
);else printe(x
);}
template
<typename T
> inline T
gcd(const T a
,const T b
){if(!b
)return a
;return gcd(b
,a
%b
);}
template
<typename T
> inline T
min(const T a
,const T b
){return a
<b
?a
:b
;}
const int maxn
=1000001;
int n
;
vector
<int>E
[maxn
];
struct ANS
{vector
<int>sz
;int maxx
,pl
;
}D
[maxn
];
int tot
;
int ans
[maxn
];
int son
[maxn
],len
[maxn
];
int res
[maxn
];
void dfs1(const int u
,const int fa
)
{for(unsigned int i
=0;i
<E
[u
].size();i
++){const int v
=E
[u
][i
];if(v
!=fa
){dfs1(v
,u
);if(len
[son
[u
]]<len
[v
])son
[u
]=v
;}}len
[u
]=len
[son
[u
]]+1;
}
void dfs2(const int u
,const int fa
)
{if(son
[u
]){dfs2(son
[u
],u
);const int ID
=ans
[u
]=ans
[son
[u
]];for(unsigned int i
=0;i
<E
[u
].size();i
++){const int v
=E
[u
][i
];if(v
!=fa
&&v
!=son
[u
]){dfs2(v
,u
);const int TO
=ans
[v
];for(rg
int j
=0;j
<len
[v
];j
++){const int P
=len
[u
]-1-len
[v
]+j
;D
[ID
].sz
[P
]+=D
[TO
].sz
[j
];if(D
[ID
].sz
[P
]>D
[ID
].maxx
)D
[ID
].maxx
=D
[ID
].sz
[P
],D
[ID
].pl
=P
;else if(D
[ID
].sz
[P
]==D
[ID
].maxx
&&P
>D
[ID
].pl
)D
[ID
].pl
=P
;}}}D
[ID
].sz
.push_back(1);if(D
[ID
].maxx
==1)D
[ID
].pl
=D
[ID
].sz
.size()-1;}else{const int ID
=ans
[u
]=++tot
;D
[ID
].sz
.push_back(1),D
[ID
].pl
=0,D
[ID
].maxx
=1;}res
[u
]=len
[u
]-D
[ans
[u
]].pl
-1;
}
int main()
{read(n
);for(rg
int i
=1;i
<n
;i
++){int u
,v
;read(u
),read(v
);E
[u
].push_back(v
),E
[v
].push_back(u
); }dfs1(1,0);dfs2(1,0);for(rg
int i
=1;i
<=n
;i
++)print(res
[i
]),putchar('\n');return 0;
}
總結
很巧妙的一個算法,不需要log而且還好寫
總結
以上是生活随笔為你收集整理的Dominant Indices(CF 1009 F)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。