模板 點分治

2022-08-02 16:36:07 字數 1884 閱讀 2192

#include using

namespace

std;

#define inf 0x3f3f3f3f

const

int n=1e+5

;int

n,m,tot,sum,rt,ans;

struct nodee[n<<1

];int

head[n],mson[n],size[n],dis[n],rem[n];

intvis[n],test[n],judge[n],q[n],query[n];

void add(int u,int v,int

w)void getrt(int u,int

fa) mson[u]=max(mson[u],sum-size[u]);

if(mson[u]u;

}void getdis(int u,int

fa)}

void calc(int

u)

for(int i=1;i<=p;++i)//

處理完這個子樹就清空judge

judge[q[i]]=0;//

特別注意一定不要用memset,會t

}void solve(intu)}

intmain()

for(int i=1;i<=m;++i) scanf("

%d",&query[i]);

mson[rt]=sum=n; //

第一次先找整棵樹的重心

getrt(1,0

); solve(rt);

//對樹進行點分治

for(int i=1;i<=m;++i)

return0;

}

距離為k

#include using

namespace

std;

typedef

long

long

ll;const

int inf=1e9+10

;const

int maxn=1e5+10

;int

head[maxn],tot;

introot,allnode,ans,n,k;

int vis[maxn],deep[maxn],dis[maxn],siz[maxn],point[maxn];//

deep[0]子節點個數(路徑長度),point為重心節點

struct

nodeedge[maxn

<<1

];void add(int u,int v,int w)//

前向星存圖

void init()//

初始化void get_root(int u,int father)//

重心 point[u]=max(point[u],allnode-siz[u]);//

儲存節點size

if(point[u]//

更新當前子樹的重心

}void get_dis(int u,int father)//

獲取子樹所有節點與根的距離

}int cal(int u,int

now)

else r--;

}return

all;

}void solve(int u)//

以u為重心進行計算

}int

main()

root=ans=0

; allnode=n;point[0]=inf;

get_root(

1,0);

solve(root);

printf(

"%d\n

",ans);

}return0;

}

點分治

點分治模板

luogu 3806 近些日子學了點分治,當然只是學了個模板。所謂點分治,使用於處理樹上路徑的一種分治手段。因為利用了重心的性質,時間複雜度可以保證呢。所謂演算法流程 選取當前子樹的重心 計算路徑總數,不管路徑是否過當前重心 後面會去重 計算起點和終點在同一顆子樹中的合法路徑 因為這條路徑不是簡單路...

點分治模板

這兩天跟著學了一手樹上點分治模板,然後有一些感悟,決定來寫一發部落格.首先,鑑於鄙人的經驗,如果想要較快速地學習乙個新演算法,肯定還是先看一道經典的例題比較好,所以我們先來一道例題.給你一棵tree,以及這棵樹上邊的距離.問有多少對點它們兩者間的距離小於等於k 輸入格式 n n 40000 接下來n...

點分治模板

bzoj1316 由於之前板子寫得太爛了,今天把它重新整理改進了一下 vis表示每個點是否已經當過根,所以注意dfs,findroot函式的計算過程中是不會對vis進行修改的 修改時只需要考慮對dfs和solve中的有關位置進行修改即可,其它部分基本不變 include using namespac...