树链剖分模板题。线段树维护每个段中的颜色数、左端点颜色、右端点颜色。

pushup: col[rt]=col[rt<<1]+col[rt<<1|1]-(Rcol[rt<<1]==Lcol[rt<<1|1]);

在合并各个链的答案时,要注意若两头颜色相同,ans--。
【教训:树链剖分题在进行建立线段树树时,要注意下面代码中的标注部分。否则会WA】
Code:
 #include<cstdio>
#include<algorithm>
using namespace std;
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define maxn 100001
int col[maxn<<],L[maxn<<],R[maxn<<],delta[maxn<<],n,m,Val[maxn],Num[maxn];
int V[maxn<<],First[maxn<<],Next[maxn<<],All_Lcol,All_Rcol,en;
bool vis[maxn];
int top[maxn],son[maxn],tot,dep[maxn],fa[maxn],siz[maxn],Map[maxn];
inline void AddEdge(const int &UU,const int &VV){V[++en]=VV;Next[en]=First[UU];First[UU]=en;}
inline void pushup(const int &rt)
{
L[rt]=L[rt<<];
R[rt]=R[rt<<|];
col[rt]=col[rt<<]+col[rt<<|]-(R[rt<<]==L[rt<<|]);
}
inline void pushdown(const int &rt)
{
if(delta[rt]!=-)
{
L[rt<<]=R[rt<<]=L[rt<<|]=R[rt<<|]=delta[rt];
delta[rt<<]=delta[rt<<|]=delta[rt];
delta[rt]=-;
col[rt<<]=col[rt<<|]=;
}
}
void buildtree(int rt,int l,int r)
{
delta[rt]=-;
if(l==r)
{
col[rt]=;
L[rt]=R[rt]=Val[Map[l]];//l是线段树中的新位置,
//Map[l]表示新位置对应的在树中的编号是谁
return;
}
int m=l+r>>;
buildtree(lson);
buildtree(rson);
pushup(rt);
}
void update(int ql,int qr,int v,int rt,int l,int r)
{
if(ql<=l&&r<=qr)
{
delta[rt]=L[rt]=R[rt]=v;//更新当前结点的标记值
col[rt]=;
return;
}
pushdown(rt);//将该节点的标记下传到孩子们
int m=l+r>>;
if(ql<=m)
update(ql,qr,v,lson);
if(m<qr)
update(ql,qr,v,rson);
pushup(rt);
}
int query(int ql,int qr,int rt,int l,int r)
{
if(ql==l)
All_Lcol=L[rt];
if(r==qr)
All_Rcol=R[rt];
if(ql<=l&&r<=qr)
return col[rt];
pushdown(rt);//将该节点的标记下传到孩子们
int m=l+r>>,res=,now1=-,now2=-;
if(ql<=m)
{
res+=query(ql,qr,lson);
now1=R[rt<<];
}
if(m<qr)
{
res+=query(ql,qr,rson);
now2=L[rt<<|];
}
res-=(now1==now2 && now1!=-);
return res;
}
inline void Update(int u,int v,int val)
{
int f1=top[u],f2=top[v];
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(u,v);
swap(f1,f2);
}
update(Num[f1],Num[u],val,,,n);
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v])
swap(u,v);
update(Num[v],Num[u],val,,,n);
}
inline int Query(int u,int v)
{
int f1=top[u],f2=top[v],ans=,t1=-,t2=-;
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(u,v);
swap(f1,f2);
swap(t1,t2);
}
ans+=query(Num[f1],Num[u],,,n);
ans-=(t1==All_Rcol);
t1=All_Lcol;
u=fa[f1];
f1=top[u];
}
if(dep[u]<dep[v])
{
swap(u,v);
swap(t1,t2);
}
ans+=query(Num[v],Num[u],,,n);
ans-=((t1==All_Rcol&&t1!=-)+(t2==All_Lcol&&t2!=-));
return ans;
}
void dfs1(int cur,int father,int depth)
{
fa[cur]=father;
dep[cur]=depth;
siz[cur]=;
for(int i=First[cur];i;i=Next[i])
if(!vis[V[i]])
{
vis[V[i]]=true;
dfs1(V[i],cur,depth+);
siz[cur]+=siz[V[i]];
if(siz[V[i]]>siz[son[cur]])
son[cur]=V[i];
vis[V[i]]=false;
}
}
void dfs2(int cur)
{
if(son[cur]&&!vis[son[cur]])
{
vis[son[cur]]=true;
top[son[cur]]=top[cur];
Num[son[cur]]=++tot;
Map[tot]=son[cur];
dfs2(son[cur]);
vis[son[cur]]=false;
}
for(int i=First[cur];i;i=Next[i])
if(son[cur]!=V[i]&&!vis[V[i]])
{
vis[V[i]]=true;
top[V[i]]=V[i];
Num[V[i]]=++tot;
Map[tot]=V[i];
dfs2(V[i]);
vis[V[i]]=false;
}
}
int Res,num;
char C;
char CH[];
inline int getint()
{
Res=;
C='*';
while(C<''||C>'')
C=getchar();
while(C>=''&&C<='')
{
Res=Res*+(C-'');
C=getchar();
}
return Res;
}
inline void putint(int x)
{
num=;
while(x>)
CH[++num]=x%,x/=;
while(num)
putchar(CH[num--]+);
putchar('\n');
}
int main()
{
int x,y,a,b,c;
char op;
n=getint();
m=getint();
for(int i=;i<=n;i++)
Val[i]=getint();
for(int i=;i<n;i++){x=getint();y=getint();AddEdge(x,y);AddEdge(y,x);}
top[]=;
Num[]=++tot;
Map[tot]=;
vis[]=true;
dfs1(,,);
dfs2();
buildtree(,,n);
for(int i=;i<=m;i++)
{
getchar();
op=getchar();
a=getint();
b=getint();
if(op=='C')
{
c=getint();
Update(a,b,c);
}
else
putint(Query(a,b));
}
return ;
}

最新文章

  1. 系统中没有邮件客户端设置autoLink=email会挂掉的问题
  2. 增量处理属性之记录模式(Record Modes)
  3. OnNcCalcSize改变标题栏等的高度
  4. increadbuild重装
  5. java.lang.OutOfMemoryError: PermGen space
  6. Redis 集合操作
  7. 1029 C语言文法定义与C程序的推导过程
  8. 第三百四十九、五十天 how can I 坚持
  9. JS内存泄露常见原因
  10. 国内最大的 Node.js 社区将 New Relic 的监控产品换成了 OneAPM
  11. 设计模式_Interpreter_解释器模式
  12. Photoshop给草坡上的人物加上大气的霞光
  13. Javascript动态生成的页面信息爬取和openpyxl包FAQ小记
  14. windows 查看端口是否被占用
  15. 学习C++后感
  16. Swift5 语言指南(六) 字符和字符串
  17. 使用 IntraWeb (17) - 基本控件之 TIWRadioButton、TIWRadioGroup、TIWCheckBox
  18. inline-block各浏览器兼容以及水平间隙问题解决方案
  19. 解决IE11下载文件 文件名乱码问题
  20. uva 10494 - If We Were a Child Again 大数除法和取余

热门文章

  1. Microsoft Visual Studio TFS 切换登录用户的方法
  2. JqGrid自定义(图片)列
  3. Fiddler--的一些使用技巧
  4. 【Python学习】解决pandas中打印DataFrame行列显示不全的问题
  5. python模块 zipfile
  6. Linux内核中链表的实现与应用【转】
  7. python设计模式之单例模式(二)
  8. (转)关于bootstrap, boosting, bagging,Rand forest
  9. mui框架 页面无法滚动解决方法
  10. leetcode 之Reorder List(25)