原題:
題意:
給出一棵樹,每條邊有邊權0或1,現在要找出有序對的對數,滿足要求:x到y的路徑不能在遇到1後再遇到0。
解析:
顯然只有四種狀態:從上往下記錄為1、0、10、01,那麼用dp記錄每個點的子樹中,下面的點與之路徑為對應情況的點數。
轉移:
設d p[
p][0
]=0,
dp[p
][1]
=1,d
p[p]
[10]=
2,dp
[p][
01]=3
dp[p][0]=0,dp[p][1]=1,dp[p][10]=2,dp[p][01]=3
dp[p][
0]=0
,dp[
p][1
]=1,
dp[p
][10
]=2,
dp[p
][01
]=3
答案:
首先是子樹每個點到roo
troot
root
的情況,因為0和1雙向,01和10只能單向,所以ans
+=2∗
(dp[
0]+d
p[1]
)+dp
[2]+
dp[3
]ans+=2*(dp[0]+dp[1])+dp[2]+dp[3]
ans+=2
∗(dp
[0]+
dp[1
])+d
p[2]
+dp[
3]。然後是每個子樹中,通過根連線的折線,列舉每個兒子,算一下可以組成的情況就行(若乙個兒子的0的數量為a[0],那麼其他地方0的數量為dp[0]-a[0])。
這裡折線在兩個端點的時候都會算一次,所以要除二。
#include
using
namespace std;
#define pill pair
#define ll long long
const
int maxn=
2e5+5;
vectorv[maxn]
;ll dp[maxn][4
];//下面有多少個點與之為此關係
ll ans;
ll ans1;
void
dfs(
int p,
int fa)
else
dp[p]
[v]++;}
ans+=2
*(dp[p][0
]+dp[p][1
])+dp[p][2
]+dp[p][3
];for(
int i=
0;i.size()
;i++);
if(v==0)
else}}
intmain()
),v[b]
.push_back()
;}dfs(1,
-1);
printf
("%lld\n"
,ans+ans1/2)
;}
2200 專項 B Cubes(stl 模擬)
原題 題意 有m個方塊,每個有座標 x,y x,y x,y 值從0到m 1,這個方塊是穩定的當且僅當 x 1,y 1 x y 1 x 1,y 1 x 1,y 1 x,y 1 x 1,y 1 x 1,y 1 x,y 1 x 1,y 1 存在方塊或者y為0,初始時穩定。你和對手輪流乙個乙個抽出所有方塊,...
app專項測試0 crash
a 作業系統 大量的裝置,各種作業系統,目前使用最多的作業系統有 android ios windows blackberry等等,它們之間的應用軟體互不相容。b 裝置 觸控式和非觸控式裝置 有限的記憶體容量,電池耗電量,螢幕尺寸 解析度等。c 網路 不同的網路和運營商,目前我國的三大運營商就有電信...
徹底搞定0x0d和0x0a
我只在arm linux c和vc 下做了試驗,請大家在接觸其它語言環境下,小心推廣,不行就自己動手做試驗,最可靠。在arm linux c和vc 下回車換行的意義如下。回車 cr ascii碼 r 十六進製制,0x0d,回車的作用只是移動游標至該行的起始位置 換行 lf ascii碼 n 十六進製...