lca倍增的途中,merge一下線性基。注意線性基是從自己開始,而倍增陣列fa[i][0]等於father,意味著,線性基倍增的區間是左閉右開的,fa陣列是左閉右閉
#include#include#include#include#include#include#include#include#include#include#include#include//#include#include#include #pragma gcc optimize(2)
#define up(i,a,b) for(ll i=a;ib;i--)
#define upd(i,a,b) for(ll i=a;i<=b;i++)
#define dwd(i,a,b) for(ll i=a;i>=b;i--)
//#define local
typedef long long ll;
typedef unsigned long long ull;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
while (ch >= '0' && ch <= '9')
return x * f;
}typedef pairpir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int n = 20010;
struct node edge[n*2];
int head[n];
int cnt = 0;
void addedge(int u, int v)
ll val[n];
int n, q;
int dep[n];
int f[n][30];
struct xxj
void insert(ll x)
else
}} }
}x[n][21];
void merge(xxj &t1, xxj t2)
}void dfs(int u, int fa)
for (int i = head[u]; ~i; i = edge[i].next) }
xxj lca(int x, int y)
} if (x == y)
dwd(i, 20, 0) }
temp.insert(val[f[x][0]]);
temp.insert(val[x]);
temp.insert(val[y]);
return temp;
}int main()
dfs(1, 0);
while (q--)
printf("%lld\n", ans);
} return 0;
}
P3292 SCOI2016 幸運數字 題解
這道題的解法是倍增 lca 線性基。下面假設你已經學會了倍增 lca 和線性基。首先回顧倍增 lca 的過程 通過倍增合併 f 到 f 上。實際上線性基也是可以合併的,合併方式就是將乙個線性基插入到另外乙個線性基裡面。因此既然線性基可以合併,那麼根據倍增 lca 的思路,我們同樣可以倍增合併線性基。...
洛谷P3292 SCOI2016 幸運數字
a 國共有 n 座城市,這些城市由 n 1 條道路相連,使得任意兩座城市可以互達,且路徑唯一。每座城市都有乙個幸運數字,以紀念碑的形式矗立在這座城市的正中心,作為城市的象徵。一些旅行者希望遊覽 a 國。旅行者計畫乘飛機降落在 x 號城市,沿著 x 號城市到 y 號城市之間那條唯一的路徑遊覽,最終從 ...
Luogu 3292 SCOI2016 幸運數字
bzoj 4568。感覺很板。前置技能 線性基。放一篇感覺講的比較豐富的部落格 戳這裡。首先要求在乙個序列中任意選點使得異或和最大,當然是想到線性基了。把問題轉換到樹上,如果每次詢問的序列是兩點之間的路徑,也就是說我們只要提取出樹上一條路徑的線性基就可以了吧。發現線性基滿足可以快速合併這個性質,如果...