03 並查集 帶權,分類 樹狀陣列 線段樹

2022-07-23 15:33:33 字數 2952 閱讀 6684

並查集板子題,記錄是否被修,然後每次修了以後更新相連的電腦。

//#include#include#includeusing namespace std;

typedef long long ll;

const ll max_n=2e5+100;

const ll inf=0x3f3f3f3f;

int n,xs[max_n],ys[max_n],par[max_n],d;

int fixes[max_n];

void init(int n)

}int find(int x)

void unite(int x,int y)

int main()}}

}elsereturn par[x];

}

這樣的話首先保證集合是「穩定」的,因為當\(k\)就是集合的根節點時,\(dis[k]=0\),就不會多一次查詢而改變(我一開始就卡在這了),且在未穩定下來前會不斷更新。

然後在合併時,假設是\(x\)和\(y\),要把\(x\)接在\(y\)尾部,所以先給\(root_x\)加上\(s[y]\),然後再把\(x\)集合的元素個數加到\(y\)上並讓這兩個相等:

void unite(int x,int y)

}

但是這樣就只更新了\(x\)所在集合的根節點,所以在每次詢問前都會呼叫\(find\)函式,就會把這個新的距離更新到整個集合(這個順序真的一點都不能亂),然後就是普通的模擬了。

#includeusing namespace std;

typedef long long ll;

const ll max_n=3e4+100;

const ll inf=0x3f3f3f3f;

ll n,s[max_n],par[max_n],d,dis[max_n];

void init(int n)elsefixes[max_n];

bool cmp(fix a,fix b)

sort(fixes,fixes+m,cmp);

ll res,check=0;

for(int i=0;i分類並查集板子題,維護三個並查集代表該動物分別處於a,b或c。情況1需要判斷是否互為食物,否則合併對應集合中元素;情況2需要判斷是否為同一物種或者捕食關係相反,否則合併相鄰的集合元素。還會卡時間,只能用scanf,cin加速也不行。

#include#include//#includeusing namespace std;

typedef long long ll;

const ll max_n=1e5+6e4;

const ll inf=0x3f3f3f3f;

int n,m,par[max_n];

void init(int n)

int r1=find(x),r2=find(y),r3=find(x+n);

int r4=find(y+n),r5=find(x+2*n),r6=find(y+2*n);

if(type==1)

}else

}}printf("%lld\n",ans);

return 0;

}

板子題,區間修改維護乙個差分

//#include#includeusing namespace std;

typedef long long ll;

const ll max_n=6e5+100;

const ll inf=0x3f3f3f3f;

ll n,m,a[max_n];

int lowbit(int x)

struct ftree

}ll getsum(ll pos)

return res;

}};int main()

tree.plus(a[1],1);

for(int i=2;i<=n;i++)

while(m--)else^r^^r^r}}}

\)過程就省略了,就是直接加起來然後合併同類項,這個應該可以當成規律記起來。然後就是裸的樹狀陣列了。

#include//#includeusing namespace std;

typedef long long ll;

const ll max_n=1e5+1000;

const ll inf=0x3f3f3f3f;

ll n,m,a[max_n];

ll lowbit(ll x)

struct ftree

}ll getsum(ll pos)

return res;

}};int main()

tree1.plus(a[1],1);tree2.plus(a[1],1);

for(ll i=2;i<=n;i++)

while(m--)else

ll rs(ll x)

ll mid(ll l,ll r)

//k為根節點,全域性查詢是k=1

void push_up(ll k)

void push_down(ll k,ll l,ll r)

}//l和r為需要建樹的原陣列區間

void build(ll k,ll l,ll r)else

}//單點修改

void update(ll pos,ll val,ll l,ll r,ll k)elseelse

push_up(k);}}

//區間修改

void update(ll l,ll r,ll val,ll l,ll r,ll k)else

}ll ask(ll l,ll r,ll l,ll r,ll k)else

if(r>m)

return res;}}

}tree;

ll n,m;

int main()else

}return 0;

}

並查集,帶權並查集

題意 ignatius過生日,客人來到,他想知道他需要準備多少張桌子。然而一張桌子上面只能坐上相互熟悉的人,其中熟悉可定義成為a與b認識,b與c認識,我們就說a,b,c相互熟悉 例如a與b熟悉and b與c熟悉,d與e熟悉,此時至少需要兩張桌子。輸入 t表示樣例個數,n表示朋友個數,朋友從1到n編號...

帶權並查集

食物鏈 time limit 1000ms memory limit 10000k total submissions 71395 accepted 21146 description 動物王國中有三類動物a,b,c,這三類動物的食物鏈構成了有趣的環形。a吃b,b吃c,c吃a。現有n個動物,以1 n...

帶權並查集 then

問題 b 便 時間限制 2 sec 記憶體限制 512 mb 提交 50 解決 14 題目描述 給出乙個r c的棋盤.共有r行c列,r c個格仔.現要在每個格仔都填乙個非負整數.使得任意乙個2 2的正方形區域都滿足這樣的性質 左上角的數字 右下角的數字 左下角的數字 右上角的數字.有些格仔已經確定,...