學習筆記 樹上莫隊

2022-04-29 23:36:08 字數 4560 閱讀 2120

其實樹上莫隊是乙個尤拉序而已嘛,像普通的莫隊,特判一下出現過兩次的值就行了

設 \(st_i\) 為 \(i\) 進棧的時間,\(ed_i\) 為 \(i\) 出棧的時間,\(dfn_x,那麼就可以分兩種情況:

1、\(y\) 在 \(x\) 子樹中,也就是 \(lca(x,y)=x\),那麼區間轉化成 \([st_x,st_y]\)

2、\(y\) 不在 \(x\) 子樹中,也就是 \(lca(x,y)\not =x\),那麼區間轉化成 \([ed_x,st_y]\)

然後就是板子了

for(int i=1;i<=m;i++)

else

}

其實我國慶的時候就學了,只不過我一直 \(wa\)...後來從倍增換成樹剖,重構一遍**就 \(a\) 了

\(code\ below:\)

#include using namespace std;

const int maxn=100000+10;

int n,m,a[maxn],mp[maxn],vis[maxn],cnt[maxn],ans[maxn],st[maxn],ed[maxn],p[maxn<<1],tim,blo,now;

int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;

int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn];

struct queryq[maxn];

bool cmp(query a,query b)

int update(int x)

else if(++cnt[a[x]]==1) now++;

vis[x]^=1;

}int main()

else

}sort(q+1,q+m+1,cmp);

int l=1,r=0;

for(int i=1;i<=m;i++)

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

return 0;

}

其實就是特判一下 \(cnt_a\) 和 \(cnt_b\)

只不過我非常傻,離散了一下顏色,就 \(gg\) 了

\(code\ below:\)

#include #include #include #include using namespace std;

const int maxn=100000+10;

int n,m,a[maxn],mp[maxn],vis[maxn],cnt[maxn],ans[maxn],st[maxn],ed[maxn],p[maxn<<1],tim,blo,now;

int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;

int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn];

struct queryq[maxn];

bool cmp(query a,query b)

void update(int x)

else if(++cnt[a[x]]==1) now++;

vis[x]^=1;

}int main()

dfs1(1,0);dfs2(1,1);

for(int i=1;i<=m;i++)

else

} sort(q+1,q+m+1,cmp);

int l=1,r=0;

for(int i=1;i<=m;i++)

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

return 0;

}

小知識:帶修莫隊塊大小在 \(n^\) 跑的最快……不過我不會證

本人錯誤點:莫隊修改過來的時候應該先將修改的時間戳 \(+1\),再更新;莫隊修改回去的時候應該先更新,再將修改的時間戳 \(-1\)

\(code\ below:\)

#include using namespace std;

const int maxn=100000+10;

int n,m,a[maxn],mp[maxn],pos[maxn],val[maxn],vis[maxn],cnt[maxn],ans[maxn],st[maxn],ed[maxn],p[maxn<<1],tim,blo,now,cnum,qnum,an;

int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;

int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn];

struct queryq[maxn];

bool cmp(query a,query b)

inline void update(int x)

else

} }

sort(q+1,q+cnum+1,cmp);

int l=1,r=0;

for(int i=1;i<=cnum;i++)

ans[q[i].id]=now;

if(q[i].anc) update(q[i].anc);

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

return 0;

}

綜合題,求樹上路徑待修改區間眾數,不難想到帶修樹上莫隊

然後就再記錄乙個 \(f[i]\) 表示區間出現 \(i\) 次的數的個數,\(add\) 沒什麼好說的,\(del\) 就暴力找,跟 \(mex\) 一樣

\(code\ below:\)

#include #include #include #include #include using namespace std;

const int maxn=100000+10;

int n,m,a[maxn],vis[maxn],f[maxn],cnt[maxn],pos[maxn],val[maxn];

int ans[maxn],st[maxn],ed[maxn],p[maxn<<1],tim,blo,cnum,qnum,ans,now;

int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;

int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn];

struct queryq[maxn];

bool cmp(query a,query b)

inline void update(int x)

else if(++f[++cnt[a[x]]]==1) ans=max(ans,cnt[a[x]]);

vis[x]^=1;

}inline void add(int x)

inline void del(int x)

int main()

ans[q[i].id]=ans;

if(q[i].anc) update(q[i].anc);

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

} return 0;

}

樹上帶修莫隊 我20分鐘切掉的

其實差不多乙個板子,不過我被卡常了,我 \(inline+register+o_2\) 才過,最大乙個點 \(5136ms\)

// luogu-judger-enable-o2

#include #define res register int

#define ll long long

using namespace std;

const int maxn=100000+10;

int n,m,q,c[maxn],v[maxn],w[maxn],vis[maxn],cnt[maxn],pos[maxn],val[maxn],st[maxn],ed[maxn],p[maxn<<1],tim,blo,cnum,qnum,now;

int head[maxn],to[maxn<<1],nxt[maxn<<1],tot;ll ans[maxn],ans;

int top[maxn],dep[maxn],siz[maxn],son[maxn],fa[maxn];

struct queryq[maxn];

bool cmp(query a,query b)

inline void update(res x)

else ans+=(ll)v[c[x]]*w[++cnt[c[x]]];

vis[x]^=1;

}inline void del(res x)

inline void add(res x)

int main()

ans[q[i].id]=ans;

if(q[i].anc) update(q[i].anc);

}for(res i=1;i<=cnum;i++) printf("%lld\n",ans[i]);

return 0;

}

學習筆記 樹上莫隊

王室聯邦 樹分塊,參見popoqqq大神的部落格,講得很詳細 莫隊 小z的襪子 樹上莫隊 把前面兩個東西結合在一起,不要管什麼xor,就是寫乙個solve,走過的路徑賦成走過,因為lca沒走過,所以沒計算過,加進去,計算後再減去,因為lca最終是不需要的 蘋果樹 不知道對不對 include inc...

莫隊演算法學習筆記(三) 樹上莫隊

樹上莫隊的核心思想,就是將一棵樹轉化成乙個序列,然後用普通莫隊來搞。以一棵樹為例 要想對這棵樹進行樹上莫隊,我們第一步就是用乙個 s 陣列把它的括號序存下來 id 12 3456 78910 1112 1314 1516 s 12 4788 7455 2366 31 同時,我們用 i 陣列儲存每個數...

樹上莫隊演算法

繼續回來寫部落格 記錄點有意思的題目什麼的。貌似寫過這個的沒多少人 所以我也記錄一點。首先序列上的莫隊大家都應該很熟悉了 那麼樹上的莫隊要怎麼搞呢?先來看個題目 spoj cot2 求樹上兩點間路徑上有多少個不同的點權。序列上的莫隊是把詢問按照左端點分塊了 可是樹上沒有左端點,怎麼辦呢?我們把樹分塊...