BZOJ 4568 Scoi2016 幸運數字

2021-07-12 00:14:02 字數 1385 閱讀 2458

可以合併的東西都是人類互相傷害的**……

參照cogs上採礦那道題

可以用樹剖維護線性基,複雜度q(logn)^2(logw)^2

顯然會t。。。。

考慮到沒有修改

用點分治離線來做

乙個詢問如果經過當前分治根,則立即處理並不再下傳,否則下傳到相應子樹去做

複雜度nlognlogw+qlogwlogw

#include#include#include#include#include#include#include#include#include#include#define rep(i,l,r) for(int i=l;i<=r;i++)

#define per(i,r,l) for(int i=r;i>=l;i--)

#define mmt(a,v) memset(a,v,sizeof(a))

#define tra(i,u) for(int i=head[u];i;i=e[i].next)

using namespace std;

typedef long long ll;

const int n=20000+5;

const int m=200000+5;

struct linear_base

void ins(ll x)

else x^=base[i];

} ll solve()

ll operator + (linear_base &b)

}b[n];

struct edgee[n<<1];

int head[n],cnt;

void ins(int u,int v);head[u]=cnt;}

void insert(int u,int v)

bool del[n];

int getsize(int u,int fa)

int findroot(int u,int fa,int &root,int size)

flag&=((size-sz)<<1)<=size;

if(flag)root=u;

return sz;

}ll g[n];

void dfs(int u,int fa)

}int bel[n];

void dfs(int u,int fa,int root)

ll ans[m];

struct query;

vectorf[n];

void daq(int u)

int main()

rep(i,1,m));}

daq(1);

rep(i,1,m)printf("%lld\n",ans[i]);

return 0;

}

BZOJ4568 Scoi2016 幸運數字

樹上查兩點間最大異或和 樹倍增,每個點維護向上2 k個點的線性基,然後在查lca的時候合併 關於點權維護倍增略蛋疼 合併線性基的時候就直接把乙個線性基里的插到另乙個裡 複雜度o m log n log 2inf 合併的時候加點優化可以降掉乙個loginf 接下來bb一些有關線性基和最大異或和的東西 ...

BZOJ 4568 Scoi2016 幸運數字

題目大意 給你一顆樹,多個詢問,問你樹上任意兩點的路徑上選任意幾個點使得異或和最大。我是參考的claris大神的 點分治,對於詢問在兩個子樹間或者有乙個在重心上的進行回答,否則把問題用鍊錶接到詢問點所在的子樹上。具體方法可以選中重心都對每個子樹染色,染為這個子樹的根節點。在子樹處理問題之前一定要記住...

BZOJ4568 Scoi2016 幸運數字

線性基 倍增 lca 抑或和最大的問題顯然要用到線性基。本題就直接倍增維護線性基,合併出答案即可。線性基的合併就是乙個插入到另乙個中。有一點小細節就是lb i j 中維護的是從i到i的2j 級祖先的線性基,左開右閉,也就是不包括i本身的。因此查lc a a,b 的時候先把a和b的插入進去。code ...