HYSBZ 2243(染色)
题目链接:传送门
题目大意:中文题,略
题目思路:树链剖分,区间更新,区间查询。
闲谈: 只想说这道题做的好苦逼。。去长春现场赛之前就没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(染色)的更多相关文章
- hysbz 2243 染色(树链剖分)
题目链接:hysbz 2243 染色 题目大意:略. 解题思路:树链剖分+线段树的区间合并,可是区间合并比較简单,节点仅仅要记录左右端点的颜色就可以. #include <cstdio> ...
- HYSBZ 2243 染色 (树链拆分)
主题链接~~> 做题情绪:这题思路好想.调试代码调试了好久.第一次写线段树区间合并. 解题思路: 树链剖分 + 线段树区间合并 线段树的端点记录左右区间的颜色.颜色数目.合并的时候就用区间合并的 ...
- HYSBZ - 2243 染色 (树链剖分+线段树)
题意:树上每个结点有自己的颜色,支持两种操作:1.将u到v路径上的点颜色修改为c; 2.求u到v路径上有多少段不同的颜色. 分析:树剖之后用线段树维护区间颜色段数.区间查询区间修改.线段树结点中维护的 ...
- HDU 3966 & POJ 3237 & HYSBZ 2243 树链剖分
树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...
- HYSBZ 2243
//Accepted 18440 KB 5556 ms /* source:HYSBZ 2243 time :2015.5.29 by :songt */ /*题解: 树链剖分 */ #include ...
- BZOJ 2243 染色 | 树链剖分模板题进阶版
BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...
- HDU 3966 & POJ 3237 & HYSBZ 2243 & HRBUST 2064 树链剖分
树链剖分是一个很固定的套路 一般用来解决树上两点之间的路径更改与查询 思想是将一棵树分成不想交的几条链 并且由于dfs的顺序性 给每条链上的点或边标的号必定是连着的 那么每两个点之间的路径都可以拆成几 ...
- BZOJ 2243 染色 (线段树+树链剖分)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 9895 Solved: 3735[Submit][Status ...
- BZOJ 2243 染色(树链剖分好题)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 7971 Solved: 2990 [Submit][Stat ...
随机推荐
- nodejs http代理请求
一些免费到代理地址 http://www.xicidaili.com/nn https://proxy.l337.tech/txt http://www.66ip.cn/nm.html 以下代码可以测 ...
- cocos2dx, 重新initWithSpriteFrameName与重新setTexture()+setTextureRect()区别
比如我们有一个sprite是通过createWithSpriteFrameName创建的,现在我们需要为其更换贴图,有两种方法: 一种方法是再次调用createWithSpriteFrameName, ...
- 列表的append方法和extend方法
1.举例说明列表的append方法和extend l = ["zhy",666] l.extend(["edit","sdd"]) prin ...
- HttpOperater-模拟HTTP操作类
using System; using System.IO; using System.Linq; using System.Net; using System.Text; using System. ...
- [Jobdu] 题目1544:数字序列区间最小值
题目描述: 给定一个数字序列,查询任意给定区间内数字的最小值. 输入: 输入包含多组测试用例,每组测试用例的开头为一个整数n(1<=n<=100000),代表数字序列的长度.接下去一行给出 ...
- Oracle宣布很多其它的Java 9 新特性
随着Oracle确认了其余的4个Java 9特性,下一代Java的计划開始变得更清晰了,Oracle已经发布了第二套Java 9特性.自从Oracle在今年早些时候宣布了3个新的API和模块化源代码后 ...
- Atitit.分布式远程调用 rpc rmi CORBA的关系
Atitit.分布式远程调用 rpc rmi CORBA的关系 1. 远程调用(包括rpc,rmi,rest)1 2. 分布式调用大体上就分为两类,RPC式的,REST式的1 3. RPC(远程 ...
- 悦铃文件必须是CCITT A_Law格式的,且没有被压缩
最近在给公司弄来电彩铃,用的是电信的“悦铃”业务,办理过程不想多说了..给了我个网址和账号让我登录,登录界面惨不忍睹,感觉电信根本没有要宣传这项业务的意思,像是粗制滥造外包赶工做出来的.. 当然这不是 ...
- 基于jQ+CSS3页面滚动内容元素动画特效
今天给大家分享一款基于jQ+CSS3页面滚动内容元素动画特效.这是一款基于jQuery+CSS3实现的页面滚动代码.该实例适用于适用浏览器:360.FireFox.Chrome.Safari.Oper ...
- HTTP Status 404–/webDemo/hello
现在用一排很小的字写出来,我真是个大傻逼