题目链接:传送门

题目大意:中文题,略

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

闲谈:      只想说这道题做的好苦逼。。去长春现场赛之前就没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. 使用Topshelf创建Windows服务(转)

    Calculator public class Calculator : ICalculator { public Calculator() { Logger = LogManager.GetCurr ...

  2. Guid.NewGuid().ToString()得几种格式显示

    1.Guid.NewGuid().ToString("N") 结果为:        38bddf48f43c48588e0d78761eaa1ce6 2.Guid.NewGuid ...

  3. 【Android】15.3 Notification基础知识

    分类:C#.Android.VS2015: 创建日期:2016-02-29 一.如何向用户发出通知 1.使用Toast通知用户 前台任务中的通知(Notifications)一般用于长时间显示用户正在 ...

  4. mysql 主主复制(双主复制)报错Last_SQL_Errno: 1146

    Last_Errno: 1146 Last_Error: Error 'Table 'test.user' doesn't exist' on query. Default database: 'te ...

  5. UIApplication深入学习

    多时候,我们不需要关心这个类,我们很少继承这个类,偶尔会调用这个类的api来实现一些功能,但是不可否认,这个类是iOS编程中很重要的一个概念.UIApplication的核心作用是提供了iOS程序运行 ...

  6. 02、Windows Phone 套接字(Socket)实战之服务器端设计

    这里主要写 PC 服务器端的逻辑,UI 使用的是 WPF,因为 WPF 比普通的 WinForm 的流式布局 更容易控制,而且比 WinForm 美观一些,显示截图: 一.页面 UI MainWind ...

  7. jQuery元素操作1

    元素操作 1.2.1 高度和宽度 $(“div”).height(); // 高度 $(“div”).width(); // 宽度 .height()方法和.css(“height”)的区别: 1. ...

  8. Android基础总结(一)项目结构,事件

    Android项目的目录结构 Activity:应用被打开时显示的界面 src:项目代码 R.java:项目中所有资源文件的资源id Android.jar:Android的jar包,导入此包方可使用 ...

  9. Cocos2d-x 3.0final 终结者系列教程07-画图节点Node

    在Cocos2d-x中全部能看到的都是引擎调用底层图形库函数绘制完毕的. Cocos2d-x将屏幕全部要绘制的全部内容逻辑上保存到一个场景Scene中(尺寸通常会和屏幕大小一致) 而在Scene中又包 ...

  10. 小贝_redis 高级应用-事务

    redis高级应用-事务 一.redis的事务 二.redis实现事务 三.redis事务问题 一.redis的事务 事务提供了一种"将多个命令打包,然后一次性.按顺序地运行"的机 ...