莫名RE,甚至我还不能保证我代码有没有其他跟输出答案正确与否的错误 code:
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
const int MAXN = 4e6 + 17;
const int INF = 1e9 + 17;
struct node
{
int v,next;
}e[MAXN];
int head[MAXN],size[MAXN],dep[MAXN],father[MAXN],son[MAXN],seg[MAXN],rev[MAXN],top[MAXN],val[MAXN];
int lc[MAXN],rc[MAXN],mark[MAXN],sum[MAXN],color[2],last[2],L,R,cl,cr;
int n,m,tot;
void add(int u,int v)
{
e[++tot].v = v;
e[tot].next = head[u];
head[u] = tot;
}
void dfs1(int u,int f)
{
father[u] = f;
size[u] = 1;
dep[u] = dep[f] + 1;
for(int i = head[u];i;i = e[i].next)
{
int v = e[i].v;
if(!dep[v])
{
dfs1(v,u);
size[u] += size[v];
if(size[v] > size[son[u]])son[u] = v;
}
}
}
void dfs2(int u)
{
if(son[u])
{
seg[son[u]] = ++seg[0];
rev[seg[0]] = son[u];
top[son[u]] = top[u];
dfs2(son[u]);
}
for(int i = head[u];i;i = e[i].next)
{
int v = e[i].v;
if(!seg[v])
{
seg[v] = ++seg[0];
rev[seg[0]] = v;
top[v] = v;
dfs2(v);
}
}
}
void build(int k,int l,int r)
{
mark[k] = -1;
if(l == r)
{
lc[k] = rc[k] = val[rev[l]];
sum[k] = 1;
return;
}
int mid = (l + r) >> 1;
build(k << 1,l,mid);
build(k << 1|1,mid + 1,r);
if(rc[k << 1] != lc[k << 1|1])sum[k] = sum[k << 1] + sum[k << 1|1];
else sum[k] = sum[k << 1] + sum[k << 1|1] - 1;
lc[k] = lc[k << 1];
rc[k] = rc[k << 1|1];
}
void pushdown(int k,int c)
{
mark[k] = c;
lc[k] = rc[k] = c;
sum[k] = 1;
}
void charge(int k,int l,int r,int x,int y,int c)
{
if(l >= x && r <= y)
{
mark[k] = c;
sum[k] = 1;
lc[k] = rc[k] = c;
return;
}
int mid = (l + r) >> 1;
if(mark[k] != -1)
{
pushdown(k << 1,mark[k]);
pushdown(k << 1|1,mark[k]);
mark[k] = -1;
}
if(x <= mid)charge(k << 1,l,mid,x,y,c);
if(mid < y)charge(k << 1|1,mid + 1,r,x,y,c);
if(rc[k << 1] != lc[k << 1|1])sum[k] = sum[k << 1] + sum[k << 1|1];
else sum[k] = sum[k << 1] + sum[k << 1|1] - 1;
lc[k] = lc[k << 1];
rc[k] = rc[k << 1|1];
}
void change(int u,int v,int c)
{
int fu = top[u];
int fv = top[v];
while(fu != fv)
{
if(dep[fu] < dep[fv])swap(u,v),swap(fu,fv);
charge(1,1,n,seg[fu],seg[u],c);
u = father[fu];
fu = top[u];
}
if(seg[u] > seg[v])swap(u,v);
charge(1,1,n,seg[u],seg[v],c);
}
int query(int k,int l,int r,int x,int y)
{
int ans = 0;
if(l >= x && r <= y)
{
if(L > l)
{
L = l;
cl = lc[k];
//cout << "l" << lc[k] << endl;
}
if(R < r)
{
R = r;
cr = rc[k];
//cout << "r" << rc[k] << endl;
}
return sum[k];
}
int mid = (l + r) >> 1;
if(mark[k] != -1)
{
pushdown(k << 1,mark[k]);
pushdown(k << 1|1,mark[k]);
mark[k] = -1;
}
int right,left;
left = right = 0;
if(x <= mid)
{
ans += query(k << 1,l,mid,x,y);
// cout << l << ' ' << mid << ' ' << ans << endl;
right = rc[k << 1];
}
if(mid < y)
{
ans += query(k << 1|1,mid + 1,r,x,y);
// cout << mid + 1 << ' ' << r << ' ' << ans << endl;
left = lc[k << 1|1];
}
if(left & right)
{
if(right == left)
{
ans--;
//cout << l << ' ' << r << endl;
}
}
if(rc[k << 1] != lc[k << 1|1])sum[k] = sum[k << 1] + sum[k << 1|1];
else sum[k] = sum[k << 1] + sum[k << 1|1] - 1;
lc[k] = lc[k << 1];
rc[k] = rc[k << 1|1];
return ans;
}
int check(int u,int v)
{
int fu = top[u];
int fv = top[v];
int ans = 0;
int k = 0;
while(fu != fv)
{
if(dep[fu] < dep[fv])swap(u,v),swap(fu,fv),k ^= 1;
L = INF;
R = 0;
cl = -1;
cr = -1;
ans += query(1,1,n,seg[fu],seg[u]);
if(cr == color[k])ans--;
// cout << seg[fu] << ' ' << seg[u] << ' ' << ans << endl;
u = father[fu];
fu = top[u];
last[k] = L;
color[k] = cl;
}
L = INF;
R = 0;
cl = -1;
cr = -1;
if(seg[u] > seg[v])swap(u,v);
ans += query(1,1,n,seg[u],seg[v]);
int opt;
if(last[0] > last[1])opt = 1;
else opt = 0;
if(cl == color[opt])ans--;
if(cr == color[opt^1])ans--;
color[0] = color[1] = last[0] = last[1] = 0;
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;i += 1)
scanf("%d",&val[i]);
for(int i = 1,u,v;i <= n - 1;i += 1)
{
scanf("%d%d",&u,&v);
add(u,v);
}
dfs1(1,0);
rev[1] = seg[0] = seg[1] = top[1] = 1;
dfs2(1);
build(1,1,n);
/*cout << "seg:";
for(int i = 1;i <= n;i += 1)
cout << seg[i] << ' ';*/
string s;
for(int i = 1,u,v,c;i <= m;i += 1)
{
cin >> s;
if(s[0] == 'C')
{
scanf("%d%d%d",&u,&v,&c);
change(u,v,c);
}
else {
scanf("%d%d",&u,&v);
printf("%d\n",check(u,v));
}
}
return 0;
}