BZOJ 3697 採藥人的路徑 點分治

2021-09-26 20:14:30 字數 1191 閱讀 9139

好久不做點分治的題了,正好在聯賽之前抓緊複習一下.

先把邊權為 $0$ 的置為 $-1$.

定義幾個狀態:

$f[dis][0/1],g[dis][0/1]$

其中 $f$ 代表在當前遍歷的子樹內的答案.

其中 $f[dis][0]$ 表示到根節點距離為 $dis$,沒有遇到平衡點的個數,$f[dis][1]$ 表示遇到平衡點的個數.

然後就把 $f$ 和 $g$ 用乘法原理乘一下就可以了.

注意要及時清空.

#include #include #include #define n 200004 

#define ll long long

#define bu(i) bu[i+n]

#define f(i,j) f[i+n][j]

#define g(i,j) g[i+n][j]

#define setio(s) freopen(s".in","r",stdin)

using namespace std;

ll ans=0;

int n,edges,sz,maxdep,root;

int hd[n],to[n],nex[n],val[n],mx[n],size[n],vis[n],f[n][2],g[n][2],bu[n<<1],tmp[n];

void add(int u,int v,int c)

void getroot(int u,int ff)

void dfs(int x,int ff,int dep)

void calc(int x)

for(j=-maxdep;j<=maxdep;++j) g(j,0)+=f(j,0),g(j,1)+=f(j,1);

for(j=-maxdep;j<=maxdep;++j) f(j,0)=f(j,1)=0;

} for(j=-maxx;j<=maxx;++j) g(j,0)=g(j,1)=0;

}void solve(int x)

int main()

mx[0]=n,sz=n,getroot(1,0),solve(root),printf("%lld\n",ans);

return 0;

}

BZOJ3697 採藥人的路徑

給定一棵樹,找一些路徑滿足,路徑上0,1數量相等,並在路徑上找到乙個點 休息站 改點到路徑兩端上0,1數量也相等,同一條路徑點不同,記為不同,詢問有多少條路徑滿足條件 點分治 對於乙個點 u 我們遍歷每棵子樹中的節點 v,求出di s u,v 我們記錄這條路徑上有無節點 t 使得di s v,t 0...

bzoj3697 採藥人的路徑

這是個思路題,對我這樣的zz 來說可能已經接近自己想出來的極限了。一看統計符合條件的路徑條數,肯定是點分治,而且肯定是靜態的。首先把邊權變成 1 和 1 那麼一條路徑陰陽平衡也就是說它的權值和等於 0 根據點分治的過程,可知重心和路徑是一對多的關係,而且一條路徑只會對應乙個重心,就是說每條路徑都只會...

bzoj3697 採藥人的路徑

description 採藥人的藥田是乙個樹狀結構,每條路徑上都種植著同種藥材。採藥人以自己對藥材獨到的見解,對每種藥材進行了分類。大致分為兩類,一種是陰性的,一種是陽性的。採藥人每天都要進行採藥活動。他選擇的路徑是很有講究的,他認為陰陽平衡是很重要的,所以他走的一定是兩種藥材數目相等的路徑。採藥工...