P3292 SCOI2016 幸運數字

2022-05-21 04:51:12 字數 1599 閱讀 9527

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。感覺很板。前置技能 線性基。放一篇感覺講的比較豐富的部落格 戳這裡。首先要求在乙個序列中任意選點使得異或和最大,當然是想到線性基了。把問題轉換到樹上,如果每次詢問的序列是兩點之間的路徑,也就是說我們只要提取出樹上一條路徑的線性基就可以了吧。發現線性基滿足可以快速合併這個性質,如果...