牛客-乃爱与城市拥挤程度【树形dp】
正題
題目鏈接:https://ac.nowcoder.com/acm/contest/1100/B
題目大意
nnn個點的一棵樹,對于每個點求
解題思路
對于第一問我們先考慮在子樹中的,sizx,zsiz_{x,z}sizx,z?表示距離該點不超過zzz的點數,有轉移sizx,z=1+∑x?>ysizy,z?1siz_{x,z}=1+\sum_{x->y}siz_{y,z-1}sizx,z?=1+x?>y∑?sizy,z?1?
然后那么我們每個點的答案我們就只需要計算xxx的祖宗節點即可,
定義xxx的第zzz代祖宗表示為fazfa_zfaz?,有貢獻sizfaz,k?z?sizfaz?1,k?z?1siz_{fa_z,k-z}-siz_{fa_{z-1},k-z-1}sizfaz?,k?z??sizfaz?1?,k?z?1?
這樣我們就解決了第111問,考慮第222問
依舊先考慮子樹定義mulx,zmul_{x,z}mulx,z?表示距離為zzz時xxx點子樹中的值(注意不能計算xxx點,因為xxx的價值還不知道)
有mulx,z=∏x?>y(muly,z?1?sizy,z?1)mul_{x,z}=\prod_{x->y} (mul_{y,z-1}*siz_{y,z-1})mulx,z?=x?>y∏?(muly,z?1??sizy,z?1?)
那依舊對于每一個的子樹祖宗,有貢獻mulfaz,k?zmulfaz?1,k?z?1\frac{mul_{fa_z,k-z}}{mul_{fa_{z-1,k-z-1}}}mulfaz?1,k?z?1??mulfaz?,k?z??
但是該點的值還沒有計算,我們發現對于該點的值就是它和所有往上的祖宗的sizfaz,k?z+sizfaz?1,k?z?1siz_{fa_z,k-z}+siz_{fa_{z-1},k-z-1}sizfaz?,k?z?+sizfaz?1?,k?z?1?之和,在上一問計算時計入即可。
時間復雜度O(nk)O(nk)O(nk)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=1e5+100,XJQ=1e9+7; struct node{ll to,next; }a[N*2]; ll n,k,tot,ls[N],f[N],g[N],siz[N][15],mul[N][15],fa[N],num[15]; void addl(ll x,ll y) {a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot; } void dfs(ll x) {for(ll j=0;j<=10;j++)siz[x][j]=mul[x][j]=1;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa[x]) continue;fa[y]=x;dfs(y);for(ll j=1;j<=10;j++){siz[x][j]+=siz[y][j-1];(mul[x][j]*=mul[y][j-1]*siz[y][j-1]%XJQ)%=XJQ;}} } ll power(ll x,ll b) {ll ans=1;while(b){if(b&1) ans=ans*x%XJQ;x=x*x%XJQ;b>>=1;}return ans; } void dfs2(ll x) {ll now=x,z=k;f[x]=(num[k]=siz[x][k]);while(--z&&fa[now]){f[x]+=siz[fa[now]][z]-siz[now][z-1];num[z]=f[x];now=fa[now];}if(fa[now])f[x]++;now=x;z=k;g[x]=mul[x][k]*f[x]%XJQ;while(--z&&fa[now]){(g[x]*=mul[fa[now]][z]*power(mul[now][z-1]*siz[now][z-1]%XJQ,XJQ-2)%XJQ)%=XJQ;(g[x]*=f[x]-num[z+1])%=XJQ;now=fa[now];}for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa[x]) continue;dfs2(y);} } int main() {scanf("%lld%lld",&n,&k);for(ll i=1;i<n;i++){ll x,y;scanf("%lld%lld",&x,&y);addl(x,y);addl(y,x);}dfs(1);dfs2(1);for(ll i=1;i<=n;i++)printf("%lld ",f[i]);putchar('\n');for(ll i=1;i<=n;i++)printf("%lld ",g[i]); }總結
以上是生活随笔為你收集整理的牛客-乃爱与城市拥挤程度【树形dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: P2519-[HAOI2011]prob
- 下一篇: 宏碁第三季度合并营收 674.45 亿元