0%

思路讲解

【线性基【力扣周赛 460】】 https://www.bilibili.com/video/BV1pm8vzAEXx/?share_source=copy_web&vd_source=6ca0bc05e7d6f39b07c1afd464edae37

视频,我只推荐灵茶山艾府

AC代码

https://www.luogu.com.cn/record/228289095

心路历程(WA,TLE,MLE……)

思路讲解

下面把**“任意两点 u → v 经过哪些关键边”在 O(log n) 时间求出的方法补充得更细一些。**

给出两种写法:


A) 更快也更简单的一行式(查询 O(1))

思路:

从根结点 root 出发 DFS,一路累积“根 → 当前结点”这条链上出现的关键边集合,记到数组 upMask[] 里。

1
2
upMask[child] = upMask[parent] | (当前这条边是关键边 ? (1<<bit) : 0);

因为一条树上路径 (u,v) 可以分解成

root → u 和 root → v 两条链,而它们公共的部分(root → lca)在两条链里都会出现一次,

用异或就能把它抵消掉,所以

1
2
pathMask(u,v) = upMask[u] ^ upMask[v];     // O(1)

整条路径上恰好出现一次的边,正好就是 u-v 之间的那条简单路径。

  • 预处理:一次 DFS,O(n)。

  • 查询:连 LCA 都不用求,完全 O(1)。

AC代码

心路历程(WA,TLE,MLE……)

思路讲解

这个子集确实还可以,不是很难,就是卡一下这个折半搜索01树。

你用线性基做基本不会被卡。

AC代码

心路历程(WA,TLE,MLE……)

思路讲解

【线性基【力扣周赛 460】】 https://www.bilibili.com/video/BV1pm8vzAEXx/?share_source=copy_web&vd_source=6ca0bc05e7d6f39b07c1afd464edae37

AC代码

https://leetcode.cn/problems/partition-array-for-maximum-xor-and-and/submissions/649067731/

心路历程(WA,TLE,MLE……)

思路讲解

核心就是知道可以发多少个月,就可以知道总共可以发多少个人次,一个人最多可以发多少钱。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
auto check=[&](ll mid){
// 我们一共可以给mid*P个人次发钱。
ll chance=mid*P;
vpll rem;
ll ans=0;
FOR(i,1,N){
ll a=A[i-1];
ll ci=min({a/K,mid,chance});
chance-=ci;
ans+=ci*K;
ll r=a-K*ci;
if(r>0) rem.EB(r,mid-ci);
}
if(chance<=0){
if(ans>=M){
return true;
}else{
return false;
}
}
sort(all(rem),greater<>());
for(auto [v,ci]:rem){
if(chance==0) break;
if(ci>0) ans+=v,chance--;
}
if(ans>=M){
return true;
}else{
return false;
}
};

AC代码

https://acm.hdu.edu.cn/contest/view-code?cid=1176&rid=8395

心路历程(WA,TLE,MLE……)