HDU4812 D Tree(樹的點分治)

2022-05-02 19:12:07 字數 1637 閱讀 8179

題目大概說給一棵有點權的樹,輸出字典序最小的點對,使這兩點間路徑上點權的乘積模1000003的結果為k。

樹的點分治搞了。因為是點權過根的兩條路徑的lca會被重複統計,而注意到1000003是質數,所以這個用乘法逆元搞一下就ok了。還有要注意「治」的各個實現,把時間複雜度「控制」在o(nlogn)。

wa了幾次,wa在漏了點到子樹根的路徑,還有每次分治忘了清空陣列。

1 #include2 #include3 #include4

using

namespace

std;

5#define inf (1<<30)

6#define maxn 111111

7struct

edgeedge[maxn<<1

];10

intne,head[maxn];

11void addedge(int u,int

v)14

bool

vis[maxn];

15int

mini,cen,size[maxn];

16void getsize(int u,int

fa)24}25

void getcen(int u,int fa,int &tot)

33if(resu;34}

35int getcen(int

u)41

long

long ine(long

long

a)48

return

res;49}

50int

n,k,val[maxn];

51int

ansx,ansy;

52int record[1000003

],tn,tmpx[maxn],tmpy[maxn],all[maxn],an;

53void dfs(int u,int fa,long

long dist,int &top)else63}

64 tmpx[tn]=u; tmpy[tn]=dist; ++tn;

65 all[an++]=dist;

66for(int i=head[u]; i!=-1; i=edge[i].next)71}

72void conquer(int

u)84}85

for(int i=0; i0;86

}87void divide(int

u)96}97

intmain()

103 ne=0

;104 memset(head,-1,sizeof

(head));

105for(int i=1; ii)

110 memset(vis,0,sizeof

(vis));

111 ansx=ansy=inf;

112 divide(1

);113

if(ansx==inf) puts("

no solution");

114else printf("

%d %d\n

",ansx,ansy);

115}

116return0;

117 }

樹的點分治 HDU4812 D Tree

題目傳送門 這次英語題應該比較好懂吧 大意是給定一棵有n nn個點的樹,每個點有權值v iv i vi 求是否存在一條路徑使得路徑上所有點的權值的乘積mod 106 3 bmod 10 6 3 mod106 3為k kk,輸出路徑首尾編號,若有多解輸出字典序最小的解。貌似很像不虛就是要ak?現在求路...

HDU 4812 D Tree 點分治 逆元

題目要求在樹上找到一條鏈使得這條鏈上的點的乘積模mod等於k,求鏈首尾字典序最小的一條 看到題目就能知道是乙個點分治的題目,將樹按照重心分治之後,就是要統計以重心為根的子樹中,過樹根的mod為k的鏈字典序最小的一條,這裡的統計必需是在時間複雜度o n 以下才能過 pragma comment lin...

在struts裡的實現dtree通用樹型結構

在這裡簡單介紹一下該樹型結構的做法 2 我們看看樹的主要字段 id 主鍵 pid 父類id name 結點名稱 url 結點連線的url title 類似alt的一種結點顯示內容 target 連線開啟的目標 icon 檔案,沒有指定將使用預設的 open boolean型別,結點是否開啟。上面是用...