lyk有一棵樹,它想給這棵樹重標號。
重標號後,這棵樹的所有葉子節點的值為它到根的路徑上的編號最小的點的編號。
這棵樹的煩惱值為所有葉子節點的值的乘積。
lyk想讓這棵樹的煩惱值最大,你只需輸出最大煩惱值對1e9+7取模後的值就可以了。
注意一開始1號節點為根,重標號後這個節點仍然為根。
資料保證葉子節點個數<=20,n<=100000
容易想到深度越大的節點編號要盡量小,且從葉子到根節點經過的節點的編號是遞增的
因為我們要讓葉子節點編號盡量的大,所以能往上多編號就多編號
注意到乙個節點子樹內的點的編號如果都確定了,為了符合上述貪心策略,就可以直接確定這個點的編號了,為\(size+1\)
然後發現兒子數為 \(1\)的節點是沒有用的,因為可以直接一路確定上去,只用知道這樣的點的個數即可
把這些點去掉之後,由於葉子節點數只有\(20\),所以去掉之後,剩下的點不超過 \(39\) 個了,於是可以暴力做了
把葉子節點狀壓 , 設 \(f[i]\) 表示狀態為 \(i\) 的節點煩惱值的最大值
讓能確定編號的點都確定好,得到下乙個節點的編號,列舉把這個編號給哪個葉子即可
#includeusing namespace std;
const int n=1e5+10,mod=1e9+7;
int head[n],nxt[n<<2],to[n<<2],num=0,n,in[n],sz[n],v[n],leaf[n];
int head[n],b[n],cnt=0,sum=0,w[n],g[1<<20];double f[1<<20];
inline void link(int x,int y)
inline void link(int x,int y)
inline void dfs(int x,int last,int fa)
for(int i=head[x];i;i=nxt[i])if(to[i]!=last)dfs(to[i],x,fa);
}int main()
double t=f[i]*id;
for(int j=1;j<=m;j++)
if(!(i&(1<<(j-1))) && t>f[1<<(j-1)|i])
f[1<<(j-1)|i]=t,g[1<<(j-1)|i]=1ll*id*g[i]%mod;
} cout
}
51nod1673樹有幾多愁
題目描述 lyk有一棵樹,它想給這棵樹重標號。重標號後,這棵樹的所有葉子節點的值為它到根的路徑上的編號最小的點的編號。這棵樹的煩惱值為所有葉子節點的值的乘積。lyk想讓這棵樹的煩惱值最大,你只需輸出最大煩惱值對1e9 7取模後的值就可以了。注意一開始1號節點為根,重標號後這個節點仍然為根。updat...
51nod1673 樹有幾多愁(狀壓DP)
傳送門 lyk有一棵樹,它想給這棵樹重標號。重標號後,這棵樹的所有葉子節點的值為它到根的路徑上的編號最小的點的編號。這棵樹的煩惱值為所有葉子節點的值的乘積。lyk想讓這棵樹的煩惱值最大,你只需輸出最大煩惱值對1e9 7取模後的值就可以了。注意一開始1號節點為根,重標號後這個節點仍然為根。資料保證葉子...
51nod1462 樹據結構
給一顆以1為根的樹。每個點有兩個權值 vi,ti,一開始全部是零。q次操作 讀入o,u,d o 1 對u到根上所有點的vi d o 2 對u到根上所有點的ti vi d 最後,輸出每個點的ti值 n,q 100000 有50 的資料n,q 10000 注 所有數64位整數不會爆。我們考慮用樹剖來做這...