程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu 4670 樹的點分治

hdu 4670 樹的點分治

編輯:C++入門知識

思路:首先當然是要用樹的點分治了。根節點為root,那麼經過root的合法路徑數求出來這題就解決了。因為我們可以用分治枚舉根,最後將所有根的路徑數加起來就是結果。當然這裡的根不是整棵樹的根,是子樹根。

我們為每個節點分配一個長度為30的數組記錄給定因數在每個節點權值出現的次數。如果某幾個權值相乘的值Value的三次根仍是整數的話,那麼Value在給定因數的所有冪一定是3的倍數。通過這個轉換,我們將所有的冪都對3取余,結果還是一樣。

在判斷經過root的合法路徑數時,我們進入其一個子樹,將經過的路徑因數的冪相加,判讀其是否有對立狀態存在,若存在,結果+1。所謂對立狀態就是能夠合成合法路徑的狀態。

例如因數為 2,3,5.

那麼 x節點的狀態為 0,1,2 表示2的0次冪,3的1次冪,5的2次冪。

其對立狀態就是 0,2,1。因為他這兩條路徑合成一條後,就變成了0,3,3.都是3的倍數。

狀態數的記錄,我們可以用long long 型的map。

要加棧,不然會RE。我就連續兩次RE,加了就AC了。

 comment(linker, "/STACK:1024000000,1024000000")<iostream><cstring><algorithm><cstdio><cmath><vector><map>
 Maxn 100010
 Maxm 200010
 LL __int64
 inf 0x7fffffff
 <LL,LL> head[Maxn],vi[Maxn],e,ans,num,k,n,m,prime[ cnt[<Node>,-,,,]=( i=;i<=;i++=Exp[i-]*=ans=lans= add( u,=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++=v,edge[e].v=u,edge[e].next=head[v],head[v]=e++ dfssize( u,==(i=head[u];i!=-;i==(v!=fa&&!+=(size[v]>mx[u]) mx[u]= dfsroot( r, u,(size[r]-size[u]>mx[u]) mx[u]=size[r]-(mx[u]<mi) mi=mx[u],root=(i=head[u];i!=-;i==(v!=fa&&! dfsdis( u,Node d,=(j=;j<=k;j++)
+=(-(d.cnt[j]+node[root].cnt[j])%)%*+=hash[cc];
(i=head[u];i!=-;i==(v!=fa&&!(j=;j<=k;j++=(d.cnt[j]+node[v].cnt[j])% calc( i,j,ret==]=(i=head[u];i!=-;i==(!=
            ( r=;r<sz;r++)
=(j=;j<=k;j+++=q[r].cnt[j]*++ dfs(=+=
    vi[root]=(i=head[root];i!=-;i==(!(scanf(,&n)!=,&(i=;i<=k;i++,&(i=;i<=n;i++,&,(j=;j<=k;j++(x%prime[j]==&&x!=++%=/=(x== cc=(j=;j<=k;j+++=(cc==++
        (i=;i<n;i++,&u,& 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved