题目链接:传送门

题目大意:中文题,略

题目思路:树链剖分,区间更新,区间查询。

闲谈:      只想说这道题做的好苦逼。。去长春现场赛之前就没A,回来后又做了2天才A掉,蒟蒻太菜了

     这道题也没有想象中那么难,就是代码有点长。。

     在查询的时候注意判断端点交界处如果相同则答案-1。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define mcp(x,y) memcpy(x,y,sizeof(y))
using namespace std;
#define gamma 0.5772156649015328606065120
#define MOD 1000000007
#define inf 0x3f3f3f3f
#define N 100005
#define maxn 30010
typedef pair<int,int> PII;
typedef long long LL;
LL read(){
LL x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
int n,m,k,sz,L,R;
int a[N],mrk[N<<];
struct Seg{int l,r,v;}seg[N<<];
int son[N],siz[N],id[N],tid,posi[N];
int top[N],fa[N],dep[N],head[N],hcnt;
struct Node{int to,nxt;}node[N<<];
void dfs1(int u,int f,int deep){
dep[u]=deep,fa[u]=f,siz[u]=;
for(int i=head[u];~i;i=node[i].nxt){
int e=node[i].to;
if(e==f)continue;
dfs1(e,u,deep+);
siz[u]+=siz[e];
if(!son[u]||siz[son[u]]<siz[e])
son[u]=e;
}
}
void dfs2(int u,int tp){
top[u]=tp,id[u]=++tid,posi[tid]=u;
if(!son[u])return;dfs2(son[u],tp);
for(int i=head[u];~i;i=node[i].nxt){
int e=node[i].to;
if(!id[e])dfs2(e,e);
}
}
void pushdown(int rt){
seg[rt<<].v=seg[rt<<|].v=;
seg[rt<<].l=seg[rt<<].r=mrk[rt];
seg[rt<<|].l=seg[rt<<|].r=mrk[rt];
mrk[rt<<]=mrk[rt<<|]=mrk[rt];mrk[rt]=-;
}
int query(int rt,int l,int r){
if(L<=l&&r<=R)return seg[rt].v;
int mid=l+r>>,temp=,t1=-,t2=-;
if(~mrk[rt])pushdown(rt);
if(L<=mid)t1=seg[rt<<].r,temp+=query(lson);
if(R>mid) t2=seg[rt<<|].l,temp+=query(rson);
seg[rt].l=seg[rt<<].l,seg[rt].r=seg[rt<<|].r;
seg[rt].v=seg[rt<<].v+seg[rt<<|].v-(seg[rt<<].r==seg[rt<<|].l);
temp-=(t1==t2&&t1!=-);
return temp;
}
void update(int rt,int l,int r,int v){
if(L<=l&&r<=R){seg[rt].v=,seg[rt].l=seg[rt].r=mrk[rt]=v;return;}
int mid=l+r>>;
if(~mrk[rt])pushdown(rt);
if(L<=mid)update(lson,v);
if(R>mid) update(rson,v);
seg[rt].l=seg[rt<<].l,seg[rt].r=seg[rt<<|].r;
seg[rt].v=seg[rt<<].v+seg[rt<<|].v-(seg[rt<<].r==seg[rt<<|].l);
}
int findp(int rt,int l,int r,int L){
if(l==r)return seg[rt].l;
int mid=l+r>>,temp;
if(~mrk[rt])pushdown(rt);
if(L<=mid)return findp(lson,L);
else return findp(rson,L);
}
void lca(int x,int y){
int res=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
L=id[top[x]],R=id[x];
res+=query(,,n);
L=id[x];
if(findp(,,n,id[top[x]])==findp(,,n,id[fa[top[x]]]))--res; ///看两端是否相同
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
L=id[x],R=id[y];
res+=query(,,n);
printf("%d\n",res);
}
void change(int x,int y,int v){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
L=id[top[x]],R=id[x];
update(,,n,v);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
L=id[x],R=id[y];
update(,,n,v);
}
void build(int rt,int l,int r){
if(l==r){seg[rt].l=seg[rt].r=a[posi[l]],seg[rt].v=;return;}
int mid=l+r>>;
build(lson);build(rson);
seg[rt].v=seg[rt<<].v+seg[rt<<|].v-(seg[rt<<].r==seg[rt<<|].l);
seg[rt].l=seg[rt<<].l,seg[rt].r=seg[rt<<|].r;
}
int main(){
int i,j,group,x,y,v;
n=read(),m=read();mst(head,-);mst(mrk,-);
for(i=;i<=n;++i)a[i]=read();
for(i=;i<n;++i){
x=read(),y=read();
node[hcnt].to=y;node[hcnt].nxt=head[x],head[x]=hcnt++;
node[hcnt].to=x,node[hcnt].nxt=head[y],head[y]=hcnt++;
}
dfs1(,,);dfs2(,);build(,,n);
char ch;
while(m--){
scanf(" %c",&ch);
x=read(),y=read();
if(ch=='Q') lca(x,y);
else v=read(),change(x,y,v);
}
return ;
}

HYSBZ 2243(染色)的更多相关文章

  1. hysbz 2243 染色(树链剖分)

    题目链接:hysbz 2243 染色 题目大意:略. 解题思路:树链剖分+线段树的区间合并,可是区间合并比較简单,节点仅仅要记录左右端点的颜色就可以. #include <cstdio> ...

  2. HYSBZ 2243 染色 (树链拆分)

    主题链接~~> 做题情绪:这题思路好想.调试代码调试了好久.第一次写线段树区间合并. 解题思路: 树链剖分 + 线段树区间合并 线段树的端点记录左右区间的颜色.颜色数目.合并的时候就用区间合并的 ...

  3. HYSBZ - 2243 染色 (树链剖分+线段树)

    题意:树上每个结点有自己的颜色,支持两种操作:1.将u到v路径上的点颜色修改为c; 2.求u到v路径上有多少段不同的颜色. 分析:树剖之后用线段树维护区间颜色段数.区间查询区间修改.线段树结点中维护的 ...

  4. HDU 3966 & POJ 3237 & HYSBZ 2243 树链剖分

    树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...

  5. HYSBZ 2243

    //Accepted 18440 KB 5556 ms /* source:HYSBZ 2243 time :2015.5.29 by :songt */ /*题解: 树链剖分 */ #include ...

  6. BZOJ 2243 染色 | 树链剖分模板题进阶版

    BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...

  7. HDU 3966 & POJ 3237 & HYSBZ 2243 & HRBUST 2064 树链剖分

    树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...

  8. BZOJ 2243 染色 (线段树+树链剖分)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9895  Solved: 3735[Submit][Status ...

  9. BZOJ 2243 染色(树链剖分好题)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 7971  Solved: 2990 [Submit][Stat ...

随机推荐

  1. 51单片机晶振11.0592M延时函数

    /********************************************** º¯ÊýÃû£ºdelay_ms(uint z) ÑÓʱº¯Êý(12MHZ¾§Õñ) ´Ëº¯ÊýÑ ...

  2. Js动态添加复选框Checkbox

    Js动态添加复选框Checkbox的实例方法!!! 首先,使用JS动态产生Checkbox可以采用如下类似的语句: var checkBox=document.createElement(" ...

  3. Unity3D动画面板编辑器状态属性对照表

    不推荐用AnimationUtility.SetEditorCurve问题很多,推荐AnimationCurve.AddKey.通过AnimationUtility.GetAllCurves可以获得编 ...

  4. 揭开Altera公司支持OpenCL的设计工具的神秘面纱

    将程序中处理负荷较大的工作分配给加速器LSI的“异构计算(Heterogeneous Computing)”将踏出崭新的一步.美国Altera公司将于2013年内开始面向普通用户提供可自动由按照异构计 ...

  5. Windows下ADB默认的5037port被占用,解决方式。

    Windows下可能会因为系统版本号不一样的原因导致有的系统5037port被系统进程占用.导致ADB无法使用5037port,从而导致ADB不能打开.在eclipse上跑Android程序的时候显示 ...

  6. ruby gem tips(转)

    淘宝源: https://ruby.taobao.org 升级ruby gem gem update --system 查看gem版本 gem -v 查看gem版本,gems安装目录,remote s ...

  7. 使用Crypto++库的CBC模式实现加密(二)

    前面已经有一篇介绍使用Crypto++库实现的加密的文章了,但是代码中考虑的不完全,所以就重新发了个二 C++封装: #include "zyaes.h" #include < ...

  8. Unix系统编程()发送信号的其他方式:raise和killpg

    有时,进程需要向自身发送信号,raise 函数就执行了这一任务. #include <signal.h> int raise(int sig); 在单线程程序中,调用raise相当于对ki ...

  9. am335x 打开内部 RTC

    AM335X 打开内部 RTC 过程记录. kernel version: 3.2.0 先在 make menuconfig 里面打开内部RTC的配置: make menuconfig Device ...

  10. PHP——分页显示的完善(加查询,用类简化sql语句)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...