可以合併的東西都是人類互相傷害的**……
參照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 ...