採藥人的藥田是乙個樹狀結構,每條路徑上都種植著同種藥材。
採藥人以自己對藥材獨到的見解,對每種藥材進行了分類。大致分為兩類,一種是陰性的,一種是陽性的。
採藥人每天都要進行採藥活動。他選擇的路徑是很有講究的,他認為陰陽平衡是很重要的,所以他走的一定是兩種藥材數目相等的路徑。採藥工作是很辛苦的,所以他希望他選出的路徑中有乙個可以作為休息站的節點(不包括起點和終點),滿足起點到休息站和休息站到終點的路徑也是陰陽平衡的。他想知道他一共可以選擇多少種不同的路徑。
第1行包含乙個整數n。
接下來n-1行,每行包含三個整數a_i、b_i和t_i,表示這條路上藥材的型別。
輸出符合採藥人要求的路徑數目。
71 2 0
3 1 1
2 4 0
5 2 0
6 3 1
5 7 1
1我可能學了假的點分治……
用g[i][0…1],f[i][0…1]分別表示
前面幾個子樹以及當前子樹路徑長度和為i的路徑數目
0和1用於區分路徑上是否存在字首和為i的節點(也就是可以設立中轉站的節點)
那麼當前子樹的貢獻就是f[0][0] * g[0][0] + σf [i][0] * g [-i][1] + f[i][1] * g[-i][0] + f[i][1] * g[-i][1],
其中i的範圍[-d,d],d為當前子樹的深度。
1 #include2 #include3 #include4#define n (200000+100)
5using
namespace
std;
6struct
node
7 edge[n*2
];10
intn,k,sum,root,inf;
11long
long ans,g[n][2],f[n][2
];12
int t[n*2
];13
inthead[n],num_edge,max_depth;
14int
depth[n],d[n],size[n],maxn[n],dis[n];
15bool
vis[n];
1617
void add(int u,int v,int
l)18
2425
void get_root(int x,int
fa)26
36 maxn[x]=max(maxn[x],sum-size[x]);
37if (maxn[x]x;38}
3940
void calc(int x,int
fa)41
53 t[dis[x]]--;54}
5556
void solve(int
x)5782}
83for (int i=-up; i<=up; ++i)
84 g[n-i][0]=g[n-i][1]=0;85
for (int i=head[x]; i!=0; i=edge[i].next)
86if (!vis[edge[i].to])
8793}94
95int
main()
96106 get_root(1,0
);107
solve(root);
108 printf("
%lld
",ans);
109 }
BZOJ3697 採藥人的路徑
給定一棵樹,找一些路徑滿足,路徑上0,1數量相等,並在路徑上找到乙個點 休息站 改點到路徑兩端上0,1數量也相等,同一條路徑點不同,記為不同,詢問有多少條路徑滿足條件 點分治 對於乙個點 u 我們遍歷每棵子樹中的節點 v,求出di s u,v 我們記錄這條路徑上有無節點 t 使得di s v,t 0...
bzoj3697 採藥人的路徑
這是個思路題,對我這樣的zz 來說可能已經接近自己想出來的極限了。一看統計符合條件的路徑條數,肯定是點分治,而且肯定是靜態的。首先把邊權變成 1 和 1 那麼一條路徑陰陽平衡也就是說它的權值和等於 0 根據點分治的過程,可知重心和路徑是一對多的關係,而且一條路徑只會對應乙個重心,就是說每條路徑都只會...
bzoj3697 採藥人的路徑
description 採藥人的藥田是乙個樹狀結構,每條路徑上都種植著同種藥材。採藥人以自己對藥材獨到的見解,對每種藥材進行了分類。大致分為兩類,一種是陰性的,一種是陽性的。採藥人每天都要進行採藥活動。他選擇的路徑是很有講究的,他認為陰陽平衡是很重要的,所以他走的一定是兩種藥材數目相等的路徑。採藥工...