我也不知道為什麼要寫這篇題解(明明十分休閒),糾結了好幾分鐘要不要敘述一下題意:
給定一棵樹以及乙個序列,按照序列的順序行走(從loc
[i
]loc[i]
loc[i]
走到l oc
[i+1
]loc[i+1]
loc[i+
1]),但是如果對於某乙個loc
[]
loclo
c[]已經走到過就不需要再走了,問最後的行走距離
題目分析(其實也沒啥好分析的):
首先考慮判斷起點與終點與否已經走過,如果沒有走過的話就倍增求lca
lcalc
a並且統計行走距離,然後將起點到終點的路徑上的所有點都放在以lca
lcalc
a為關鍵字的集合當中即可。
有關集合的東西並查集維護與查詢就好。
關鍵**:
#include #include #include #include #include #define db double
#define sg string
#define ll long long
#define rep(i,x,y) for(ll i=(x);i<=(y);i++)
#define red(i,x,y) for(ll i=(x);i>=(y);i--)
using namespace std;
const ll n=5e5+5;
const ll inf=1e18;
ll n,m,k,ans,f[n],dep[n],fa[n][20];
ll cnt,to[n<<1],nxt[n<<1],head[n];
inline ll read()
while(ch>='0'&&ch<='9')
return f?-x:x;
}void ins(ll x,ll y)
void dfs(ll x) }}
ll lca(ll x,ll y)
ll find(ll x)
int main()
dfs(1);
rep(i,1,m)
tmp=loc;
while(find(tmp)!=flca)
k=loc;
} }printf("%lld\n",ans);
return 0;
}
3910 火車 LCA 並查集
在樹上走顯然是求lca,然後每次走完把端點到lca路徑上的點都用並查集合並,之後如果判斷兩點所屬集合相等說明已經走過。倍增被鏈剖虐成狗系列 include include define n 500005 define ll long long using namespace std int n,m,...
bzoj3910 火車 lca 並查集
a 國有n 個城市,城市之間有一些雙向道路相連,並且城市兩兩之間有唯一 路徑。現在有火車在城市 a,需要經過m 個城市。火車按照以下規則行駛 每次 行駛到還沒有經過的城市中在 m 個城市中最靠前的。現在小 a 想知道火車經過 這m 個城市後所經過的道路數量。第一行三個整數 n m a,表示城市數量 ...
LCA法寶 並查集
由於我也是看懂的,突然發現這篇部落格特別的好!lca 最近公共祖先 我相信你現在肯定自己就可以打 了!另外注意,這裡的 f 陣列其實是用了並查集的思想 並查集詳解 倍增 inline void dfs int x,int s,int chang for reg int i 0 i g x size ...