線段樹分治學習筆記

2022-05-06 22:00:08 字數 3170 閱讀 4388

模板:洛谷p5787

用按秩合併的帶權並查集維護連通塊中點之間邊數的奇偶性來判斷是否存在負環(用棧儲存撤銷操作,複雜度 \(o(nlog^2)\)。

#include#define il inline

#define ls k<<1

#define rs k<<1|1

#define pb push_back

#define ll long long

using namespace std;

const int n=1e5+3;

struct hh;

struct kk;

int n,m,k,dep[n],fa[n],dis[n];

il int in()

il int find_f(int x)

il int find_d(int x)

struct segment);return;}

int mid=l+r>>1;

if(ll<=mid) mdy(ls,l,mid,ll,rr,x,y);

if(rr>mid) mdy(rs,mid+1,r,ll,rr,x,y);

} void solve(int k,int l,int r));

fa[fx]=fy,dis[fx]=w,dep[fy]+=(dep[fx]==dep[fy]);

}} if(l==r) puts("yes");

else solve(ls,l,mid),solve(rs,mid+1,r);

dd:for(int i=s.size()-1;~i;--i)

} }t;

int main()

cf1140f extending set of points

將 \((x,y)\) 轉化為鏈結 \(x,y+n\) 的邊,得到乙個二分圖,易得該圖中乙個連通塊的貢獻為左邊點的數量乘右邊點的數量(可以將 \((x,y)\) 看成座標幫助理解)。

並查集維護。

#include#define il inline

#define ls k<<1

#define rs k<<1|1

#define ll long long

#define pb push_back

#define m make_pair

using namespace std;

const int n=6e5+3;

int n;

map,int>mp;

map,int>::iterator it;

struct hh

void set(int n)

}f;struct kk;

struct segment

int mid=l+r>>1;

if(ll<=mid) mdy(ls,l,mid,ll,rr,u);

if(rr>mid) mdy(rs,mid+1,r,ll,rr,u);

} void solve(int k,int l,int r,ll ans));}}

int mid=l+r>>1;

if(l==r) printf("%lld ",ans);

else solve(ls,l,mid,ans),solve(rs,mid+1,r,ans);

for(int i=s.size()-1;~i;--i)

}}t;

il int in()

int main()

),mp[m(x,y)]=0;

} for(it=mp.begin();it!=mp.end();++it)

if(it->second) t.mdy(1,1,n,it->second,n,(kk));

f.set(3e5);

t.solve(1,1,n,0);

return 0;

}

洛谷p4585

垃圾題面,毀我青春。

很明顯要用可持久化trie維護。

將修改作為區間儲存發現難以維護可持久化trie。

考慮將詢問作為區間儲存,單點修改,每次到乙個節點,將這個節點所包含的修改操作放到一起建trie,複雜度 \(o(17n)\),可以接受。

總複雜度 \(o(17nlogn)\)。(交了一發結果rk1?

#include#define il inline

#define ll long long

#define pb push_back

#define ls k<<1

#define rs k<<1|1

using namespace std;

const int n=1e5+3;

int n,m,val[n],rt[n],ch[n*100][2],las[n*100],ans[n],cnt,c1,c2;

struct hh

il int new_node()

void ins(int &o,int p,int now,int x,int dep)

int ask(int o,int now,int x,int dep)

int mid=l+r>>1;

if(ll<=mid) mdy(ls,l,mid,ll,rr,u);

if(rr>mid) mdy(rs,mid+1,r,ll,rr,u);

} void solve(int k,int l,int r)

}t;int main()

; else c[++c1]=(kk);

} for(int i=1;i<=c2;++i) t.mdy(1,1,c1,max(1,q[i].day-q[i].d+1),q[i].day,q[i]);

t.solve(1,1,c1),cnt=0;

for(int i=1;i<=n;++i) rt[i]=0,ins(rt[i],rt[i-1],i,val[i],16);

for(int i=1;i<=c2;++i) ans[i]=max(ans[i],ask(rt[q[i].r],q[i].l,q[i].x,16));

for(int i=1;i<=c2;++i) printf("%d\n",ans[i]);

return 0;

}

待補:

cf938g shortest path queries

cf603e pastoral oddities

線段樹分治學習筆記

參考部落格1 參考部落格2 核心思想 適用範圍 遇到如下問題 例題 p5787 二分圖 模板 線段樹分治 對時間軸建立線段樹。維護區間內存在的邊集,用 vec to rvector vector 進行維護。查詢時從根節點出發開始遍歷,遞迴處理時將當前節點存在的邊進行合併,判斷是否為二分圖。若到達某個...

線段樹分治學習筆記

也許更好的閱讀體驗。模板題p5757 一張 n 個點的圖,有 m 條無向邊會在 l i,r i 時刻存在,求在 1,k 時刻中每個時刻整張圖是否是一張二分圖。1 leq n leq 10 5 1 leq l i leq r i leq k leq 10 5 1 leq m leq 2 times 1...

樹 點分治學習筆記

不做筆記的後果是我完全忘記了我在5個月前就學過點分治 去洛谷做題才發現的 點分治大概是用於樹上路徑的求解。點分治分4步走 1,對當前子樹找重心 固定 void getroot int u,int fa ms u max ms u tsiz siz u if ms u u 2,把樹上距離 邊權 存進臨...