全WA,hack也WA,样例过了,求错误小数据
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100002;
int n,m;
int tid;
int a[MAXN];
int fa[MAXN];
int dep[MAXN];
int siz[MAXN];
int son[MAXN];
int dfn[MAXN];
int rnk[MAXN];
int top[MAXN];
vector <int> links[MAXN];
void Dfs1(int u,int father)
{
siz[u] = 1;
fa[u] = father;
dep[u] = dep[father] + 1;
auto &link = links[u];
for(auto v : link)
{
if(v == father)
continue;
Dfs1(v,u);
siz[u] += siz[v];
if(siz[v] > siz[son[u]])
son[u] = v;
}
}
void Dfs2(int u,int topp)
{
top[u] = topp;
dfn[u] = ++tid;
rnk[tid] = u;
if(son[u] == 0)
return;
Dfs2(son[u],topp);
auto &link = links[u];
for(auto v : link)
{
if(v == fa[u] || v == son[u])
continue;
Dfs2(v,v);
}
}
struct TreeNode
{
int l,r;
int lv,rv;
int cnt;
int lazy;
};
TreeNode stree[MAXN * 4];
void SetLazy(int idx,int v)
{
TreeNode &cur = stree[idx];
cur.lv = cur.rv = v;
if(cur.l != cur.r)
cur.lazy = v;
}
void PushUp(int idx)
{
TreeNode &cur = stree[idx];
TreeNode &left = stree[idx * 2];
TreeNode &right = stree[idx * 2 + 1];
cur.lv = left.lv;
cur.rv = right.rv;
cur.cnt = left.cnt + right.cnt;
if(left.rv == right.lv)
cur.cnt--;
}
void PushDown(int idx)
{
TreeNode &cur = stree[idx];
if(cur.lazy)
{
SetLazy(idx * 2,cur.lazy);
SetLazy(idx * 2 + 1,cur.lazy);
cur.lazy = 0;
}
}
void BuildTree(int idx,int l,int r)
{
TreeNode &cur = stree[idx];
cur.l = l;
cur.r = r;
if(l == r)
{
cur.lv = cur.rv = a[rnk[l]];
cur.cnt = 1;
return;
}
int mid = (cur.l + cur.r) / 2;
BuildTree(idx * 2,l,mid);
BuildTree(idx * 2 + 1,mid + 1,r);
PushUp(idx);
}
void Change_Tree(int idx,int l,int r,int v)
{
TreeNode &cur = stree[idx];
if(l <= cur.l && cur.r <= r)
{
SetLazy(idx,v);
return;
}
PushDown(idx);
int mid = (cur.l + cur.r) / 2;
if(l <= mid)
Change_Tree(idx * 2,l,r,v);
if(mid + 1 <= r)
Change_Tree(idx * 2 + 1,l,r,v);
PushUp(idx);
}
struct Pos
{
int lv,rv;
int cnt;
};
Pos Query_Tree(int idx,int l,int r)
{
TreeNode &cur = stree[idx];
if(l <= cur.l && cur.r <= r)
return {cur.lv,cur.rv,cur.cnt};
PushDown(idx);
int mid = (cur.l + cur.r) / 2;
if(r <= mid)
return Query_Tree(idx * 2,l,r);
if(l >= mid + 1)
return Query_Tree(idx * 2 + 1,l,r);
Pos L = Query_Tree(idx * 2,l,r);
Pos R = Query_Tree(idx * 2 + 1,l,r);
Pos res = {L.lv,R.rv,L.cnt + R.cnt};
if(stree[idx * 2].rv == stree[idx * 2 + 1].lv)
res.cnt--;
return res;
}
void Change(int x,int y,int v)
{
while(top[x] != top[y])
{
if(dep[top[x]] > dep[top[y]])
{
Change_Tree(1,dfn[top[x]],dfn[x],v);
x = fa[top[x]];
}
else
{
Change_Tree(1,dfn[top[y]],dfn[y],v);
y = fa[top[y]];
}
}
if(dep[x] > dep[y])
Change_Tree(1,dfn[y],dfn[x],v);
else
Change_Tree(1,dfn[x],dfn[y],v);
}
int Query(int x,int y)
{
int res = 0;
while(top[x] != top[y])
{
if(dep[top[x]] > dep[top[y]])
{
Pos tt = Query_Tree(1,dfn[top[x]],dfn[x]);
res += tt.cnt;
Pos ttt = Query_Tree(1,dfn[fa[top[x]]],dfn[fa[top[x]]]);
if(tt.rv == ttt.lv)
res--;
x = fa[top[x]];
}
else
{
Pos tt = Query_Tree(1,dfn[top[y]],dfn[y]);
res += tt.cnt;
Pos ttt = Query_Tree(1,dfn[fa[top[y]]],dfn[fa[top[y]]]);
if(tt.rv == ttt.lv)
res--;
y = fa[top[y]];
}
//cout << x << " " << y << " " << res << endl;
}
if(dep[x] > dep[y])
res += Query_Tree(1,dfn[y],dfn[x]).cnt;
else
res += Query_Tree(1,dfn[x],dfn[y]).cnt;
return res;
}
void Check_Init()
{
cout << "dfn: ";
for(int i = 1;i <= n;i++)
cout << dfn[i] << " ";
cout << endl;
cout << "fa: ";
for(int i = 1;i <= n;i++)
cout << fa[i] << " ";
cout << endl;
cout << "dep: ";
for(int i = 1;i <= n;i++)
cout << dep[i] << " ";
cout << endl;
cout << "son: ";
for(int i = 1;i <= n;i++)
cout << son[i] << " ";
cout << endl;
cout << "top: ";
for(int i = 1;i <= n;i++)
cout << top[i] << " ";
cout << endl;
cout << "rnk: ";
for(int i = 1;i <= n;i++)
cout << rnk[i] << " ";
cout << endl;
cout << "siz: ";
for(int i = 1;i <= n;i++)
cout << siz[i] << " ";
cout << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin >> n >> m;
for(int i = 1;i <= n;i++)
cin >> a[i];
for(int i = 1;i < n;i++)
{
int u,v;
cin >> u >> v;
links[u].push_back(v);
links[v].push_back(u);
}
Dfs1(1,1);
Dfs2(1,1);
BuildTree(1,1,n);
while(m--)
{
char type;
int x,y,v;
cin >> type >> x >> y;
if(type == 'C')
{
cin >> v;
Change(x,y,v);
}
else
cout << Query(x,y) << endl;
}
return 0;
}
/*
6 10
2 2 1 2 3 2
1 2
1 3
2 4
2 5
2 6
Output:
2
*/