樹上莫隊 wowow

2022-05-09 02:09:11 字數 4619 閱讀 3518

構建:像線性的莫隊那樣,依舊是按sqrt(n)為一塊分塊。

1

int dfs(int

x)20}21

}22 st[++top]=x;

23return size+1

;24 }

然後呢,我們可以發現一些樹上莫隊的性質:

用s(v, u)代表 v到u的路徑上的結點的集合。

用root來代表根結點,用lca(v, u)來代表v、u的最近公共祖先。

那麼s(v, u) = s(root, v) xor s(root, u) xor lca(v, u)

其中xor是集合的對稱差。

簡單來說就是節點出現兩次消掉。

lca很討厭,於是再定義

t(v, u) = s(root, v) xor s(root, u)

觀察將curv移動到targetv前後t(curv, curu)變化:

t(curv, curu) = s(root, curv) xor s(root, curu)

t(targetv, curu) = s(root, targetv) xor s(root, curu)

取對稱差:

t(curv, curu) xor t(targetv, curu)= (s(root, curv) xor s(root, curu)) xor (s(root, targetv) xor s(root, curu))

由於對稱差的交換律、結合律:

t(curv, curu) xor t(targetv, curu)= s(root, curv) xors(root, targetv)

兩邊同時xor t(curv, curu):

t(targetv, curu)= t(curv, curu) xor s(root, curv) xor s(root, targetv)

即t(targetv, curu)= t(curv, curu) xor t(curv, targetv)

也就是說,更新的時候,xor t(curv, targetv)就行了。

即,對curv到targetv路徑(除開lca(curv, targetv))上的結點,將它們的存在性取反即可。

按照以上方式,我們就可以每次從u1走到u2,v1走到v2,然後要求query的時候對他們的公共祖先的存在性取反,然後求完答案後再取反回去。

bzoj3757 蘋果樹

1 #include 2 #include 3 #include 4 #include 5 #include 

6 #include 7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include 15 #include

16 #include 17

#define rep(i, l, r) for (int i = l; i <= r; ++i)

18#define req(i, l, r) for (int i = l; i >= r; --i)

19#define n 100005

20int

tot,go[n],next[n],first[n],dfn[n],belong[n];

21int st[n],res[n],n,m,x,y,fa[n][20],bin[20

],col[n],ans,ind,deep[n],blo,blonum;

22int

top,pd[n],root;

23struct

opq[n];

26int

p[n];

27void insert(int x,int

y)33

void add(int x,int

y)37

bool

cmp(op q,op w)

41int dfs(int

x)60}61

}62 st[++top]=x;

63return size+1;64

}65void reverse(int

x)71

else76}

77void solve(int u,int

v)82}83

int lca(int x,int

y)90

for (int i=19;i>=0;i--)

91if (fa[x][i]!=fa[y][i])

95if (x==y) return

x;96

else

return fa[x][0

]; 97}98

intmain()

115dfs(root);

116 blonum++;

117while (top) belong[st[top--]]=blonum;

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

124 std::sort(q+1,q+1+m,cmp);

125int t=lca(q[1].u,q[1

].v);

126 solve(q[1].u,q[1

].v);

127reverse(t);

128 res[q[1].id]=ans;

129if (p[q[1].a]&&p[q[1].b]&&q[1].a!=q[1].b) res[q[1].id]--;

130reverse(t);

131for (int i=2;i<=m;i++)

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

141 printf("

%d\n

",res[i]);

142 }

bzoj3052 wc糖果公園

1

2 #include 3 #include 4 #include 5 #include 6 #include

7 #include 8 #include 9 #include 10 #include 11 #include 12 #include 13 #include 14 #include 15 #include 16 #include

17 #include 18

#define rep(i, l, r) for (int i = l; i <= r; ++i)

19#define req(i, l, r) for (int i = l; i >= r; --i)

20#define n 200005

21long

long

res[n];

22long

long

pre[n],col[n],v[n],w[n],ans;

23int

belong[n],go[n],tot,first[n],next[n];

24int deep[n],bin[20],fa[n][17

],st[n],top,x,y,n,m,c1,c2,dfn[n],ind,blo,blonum;

25int

pd[n],p[n],qe,ty;

26struct

opc[n],b[n];

30bool

cmp(op a,op b)

36void insert(int x,int

y)42

void add(int x,int

y)46

int dfs(int

x)65}66

} 67 st[++top]=x;

68return size+1;69

}70void reverse(int

x)76

else81}

82void change(int x,int

y)88

else91}

92void solve(int x,int

y)97}98

int lca(int x,int

y)110

intmain()

124for (int i=1;i<=n;i++)

128 dfs(1

); 129

//blonum++;

130while (top) belong[st[top--]]=blonum;

131for (int i=1;i<=qe;i++)

139else

146}

147 std::sort(b+1,b+1+c2,cmp);

148for (int i=1;i<=b[1].t;i++)

149change(c[i].x,c[i].y);

150 solve(b[1].x,b[1

].y);

151int t=lca(b[1].x,b[1

].y);

152reverse(t);

153 res[b[1].id]=ans;

154reverse(t);

155for (int i=2;i<=c2;i++)

167for (int i=1;i<=c2;i++)

168 printf("

%lld\n

",res[i]);

169}

170

樹上莫隊演算法

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

樹上莫隊演算法

樹上莫隊,顧名思義就是把莫隊搬到樹上。我們從一道題目入手 sdoi2018 原題識別 spoj count on a tree ii 題目意思很明確 給定乙個 n 個節點的樹,每個節點表示乙個整數,問 u 到 v 的路徑上有多少個不同的整數。像這種不帶修改數顏色的題首先想到的肯定是樹套樹莫隊,那麼如...

樹上莫隊演算法

樹上莫隊,顧名思義就是把莫隊搬到樹上。我們從一道題目入手 sdoi2018 原題識別 spoj count on a tree ii 題目意思很明確 給定乙個 n 個節點的樹,每個節點表示乙個整數,問 u 到 v 的路徑上有多少個不同的整數。像這種不帶修改數顏色的題首先想到的肯定是樹套樹莫隊,那麼如...