其實樹上莫隊是乙個尤拉序而已嘛,像普通的莫隊,特判一下出現過兩次的值就行了
設 \(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 求樹上兩點間路徑上有多少個不同的點權。序列上的莫隊是把詢問按照左端點分塊了 可是樹上沒有左端點,怎麼辦呢?我們把樹分塊...