明明是裸树剖 竟然调了这么久好蛋疼 大概是自己比较水的原因吧 顺便+fastio来gangbang

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cstdio>
#include<cctype>
using namespace std; const int Maxn=,Maxm=Maxn; int n,m; const int D=;
char in[D],out[D/],*I=in,*O=out; inline char gc(){
return *(I++);
} inline void pc(const char& c){
*(O++)=c;
} template <typename Q>
inline void pt(Q x){
if(x==) pc('');
if(x<) pc('-'),x=-x;
static int stk[],top;
top=;
for(;x;x/=) stk[++top] = x%;
for(int i=top;i;--i) pc(stk[i]+'');
} template <typename Q>
inline void gt(Q& x){
static char c,f;
for(c=gc(),f=;!isdigit(c);c=gc()) if(c=='-') f=;
for(x=;isdigit(c);c=gc()) x=x*+c-'';
if(f) x=-x;
} struct Data {
int l,r,num;
Data (int l=-,int r=-,int num=):l(l),r(r),num(num) {}
Data operator + (const Data& rhs)const {
if(rhs.l==- && l==- ) exit(-);
if(rhs.l==-) return *this;
if(l==-) return rhs;
return Data(l,rhs.r,num+rhs.num-(r==rhs.l));
Data ret(l,rhs.r,num+rhs.num);
if(r==rhs.l) ret.num--;
return ret;
}
Data operator ~()const {
return Data(r,l,num);
}
}; int tbld[Maxn]; struct SegmentTree {
Data da[Maxn*];
int tag[Maxn*];
int lft,rgt,w; SegmentTree() {
memset(tag,-,sizeof tag);
} void build(int o,int l,int r){
if(l==r) {
da[o] = Data(tbld[l],tbld[l],);
return;
}
int mid=(l+r)>>;
build(o<<,l,mid);
build(o<<|,mid+,r);
da[o] = da[o<<] + da[o<<|];
} void add(int o,int col) {
da[o]=Data(col,col,);
tag[o]=col;
} void down(int o) {
if(tag[o]==-) return;
add(o<<,tag[o]);
add(o<<|,tag[o]);
tag[o]=-;
} void pp(int l,int r=,int w=) {
lft=l,rgt=r;
this->w=w;
} void change(int o,int l,int r) {
if(lft<=l && r<=rgt) {
add(o,w);
return;
}
down(o);
int mid=(l+r)>>;
if(lft<=mid) change(o<<,l,mid);
if(mid<rgt) change(o<<|,mid+,r);
da[o]=da[o<<]+da[o<<|];
} Data query(int o,int l,int r) {
if(lft<=l && r<=rgt) {
return da[o];
}
down(o);
int mid=(l+r)>>;
if(rgt<=mid) return query(o<<,l,mid);
if(mid<lft) return query(o<<|,mid+,r);
return query(o<<,l,mid)+query(o<<|,mid+,r);
} Data query(int l,int r){
pp(l,r);
return query(,,n);
} void change2(int l,int r,int w){
pp(l,r,w);
change(,,n);
}
} seg; int fir[Maxn],next[Maxm*],en[Maxm*];
int tot=;
void Add(int from,int to) {
en[++tot] = to;
next[tot] = fir[from];
fir[from] = tot;
} int sz[Maxn],son[Maxn],fa[Maxn],dep[Maxn]; void dfs(int u) {
sz[u] = ;
son[u] = ;
for(int k=fir[u]; k; k=next[k]) {
const int&v=en[k];
if(v == fa[u]) continue;
fa[v] = u;
dep[v] = dep[u]+;
dfs(v);
sz[u] += sz[v];
if(sz[v]>sz[son[u]]) son[u] = v;
}
} int top[Maxn],pos[Maxn],color[Maxn],clk=; void build(int u,int pre) {
top[u] = pre;
pos[u] = ++clk;
tbld[clk] = color[u];
if(son[u]) build(son[u],pre);
for(int k=fir[u]; k; k=next[k]) {
const int&v = en[k];
if(v==fa[u] || v==son[u]) continue;
build(v,v);
}
} void change(int a,int b,int c){
int ta=top[a],tb=top[b];
for(;ta!=tb;a=fa[ta],ta=top[a]){
if(dep[ta] < dep[tb] ) swap(a,b), swap(ta,tb);
seg.change2(pos[ta],pos[a],c);
}
if(dep[a]>dep[b]) swap(a,b);
seg.change2(pos[a],pos[b],c);
} Data query(int a,int b) {
int ta=top[a],tb=top[b]; Data res1,res2; for(;ta!=tb;){
if(dep[ta]>dep[tb]){
res1 = seg.query(pos[ta],pos[a]) + res1;//注意这里以及下面加的顺序,写的时候没想好,调了好久
a=fa[ta],ta=top[a];
} else {
res2 = seg.query(pos[tb],pos[b]) + res2;
b=fa[tb],tb=top[b];
}
}
// Data tmp ( seg.query(pos[b],pos[a]) );
if(dep[a]<dep[b]) return (~res1)+seg.query(pos[a],pos[b])+res2;//还有这里要取反各种坑,各种要注意顺序
// tmp=(~res2)+seg.query(pos[b],pos[a]);
// tmp=tmp+res1;
return (~res2)+seg.query(pos[b],pos[a])+res1;
} int main() {
freopen("paint.in","r",stdin);
freopen("paint.out","w",stdout); fread(in,,D,stdin); gt(n),gt(m); for(int i=;i<=n;i++) gt(color[i]); for(int u,v,i=;i<n;i++){
gt(u),gt(v);
Add(u,v);
Add(v,u);
} dfs();
build(,);
seg.build(,,n); // for(int i=1;i<=n;i++) printf("%d\n",son[i]);
// return 0; char cmd;
int a,b,c; // for(I=1;I<=m;I++)
for(;m--;){ /*if(I==2) {
Data tmp=seg.query( pos[2],pos[7] );
tmp=seg.query( pos[3],pos[4]);
tmp=seg.query( pos[2],pos[6]);
tmp=seg.query( pos[6],pos[7]);
I=2;
}*/ for(cmd=gc();cmd!='Q'&&cmd!='C';cmd=gc());
gt(a);gt(b);
if(cmd == 'Q') pt(query(a,b).num),pc('\n');
else gt(c), change(a,b,c);
} return printf(out),;
}

嗯,其实lct还是挺好写的,就是有点慢TAT

 #include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cstdio>
using namespace std; const int Maxn = ; int ch[Maxn][],p[Maxn],sz[Maxn],flip[Maxn],tag[Maxn];
int col[Maxn];
int n,m; const int D=;
char in[D],out[*],*I=in,*O=out;
#define gc (*I++)
#define pc(x) ((*O++)=x)
template <typename Q>
void gt(Q&x) {
static char c,f;
for(c=gc,f=;!isdigit(c);c=gc)if(c=='-') f=;
for(x=;isdigit(c);c=gc) x=x*+c-'';
f && (x=-x);
} struct Data {
int l,r,num;
Data(int l=-,int r=-,int num=):l(l),r(r),num(num) {}
Data operator + (const Data& rhs) const {
if(!num) return rhs;
if(!rhs.num) return *this;
return Data (l,rhs.r,num+rhs.num-(r==rhs.l));
}
void flip() {
swap(l,r);
}
}da[Maxn]; template <typename Q>
void pt(Q x){
static char stk[];
static int top;
top=;
if(x==) pc('');
for(;x;x/=) stk[++top] = x%+'';
for(;top;top--) pc(stk[top]);
} int fir[Maxn],next[Maxn*],en[Maxn*];
void Add(int from,int to) {
static int tot=;
en[++tot]=to;
next[tot]=fir[from];
fir[from]=tot;
} void add_tag(int x,int Col) {
if(x==) return;
col[x] = tag[x] = Col;
da[x] = Data(Col,Col,);
} void down(int x) {
if(flip[x]) {
swap(ch[x][],ch[x][]);
flip[ch[x][]]^=; da[ch[x][]].flip();
flip[ch[x][]]^=; da[ch[x][]].flip();
flip[x]=;
}
if(tag[x]!=-) {
add_tag(ch[x][],tag[x]);
add_tag(ch[x][],tag[x]);
tag[x]=-;
}
} bool isroot(int x){
return ch[p[x]][]!=x && ch[p[x]][]!=x;
} void update(int x) {
if(x==) return;
sz[x]=sz[ch[x][]]+sz[ch[x][]]+;
da[x]=da[ch[x][]]+Data(col[x],col[x],)+da[ch[x][]];
} void rotate(int x) {
int y=p[x],z=p[y];
int l=ch[y][]==x,r=l^;
if(!isroot(y)) ch[z][ch[z][]==y]=x;
p[ch[x][r]]=y;
p[y]=x;
p[x]=z; ch[y][l]=ch[x][r];
ch[x][r]=y; update(y);
update(x);
} void splay(int x){
static int stk[Maxn],top;
stk[top=]=x;
for(int t=x;!isroot(t);t=p[t]) stk[++top] = p[t];
for(;top;top--) down(stk[top]);
for(;!isroot(x);){
int y=p[x],z=p[y];
if(!isroot(y)){
if( (ch[y][]==x)^(ch[z][]==y) )
rotate(x);else rotate(y);
}
rotate(x);
}
} void access(int x){
for(int t=;x;x=p[t=x]){
splay(x);
ch[x][]=t;
update(x);
}
} int getroot(int x){
for(access(x),splay(x);ch[x][];x=ch[x][]);
return x;
} void cut(int x){
access(x);
splay(x);
p[ch[x][]]=;
ch[x][]=;
update(x);
} void combine(int x,int y) {
cut(x);
p[x]=y;
update(y);
} void newroot(int x){
access(x);
splay(x);
flip[x]^=;
da[x].flip();
} void dfs(int x) {
for(int k=fir[x];k;k=next[k]) {
int v=en[k];
if(v==p[x]) continue;
p[v]=x;
dfs(v);
}
} void init(){
gt(n);gt(m);
memset(tag,-,sizeof(*tag)*(n+));
for(int i=;i<=n;i++) {
gt(col[i]);
sz[i]=;
da[i] = Data( col[i],col[i],);
}
for(int u,v,i=;i<n;i++) {
gt(u),gt(v);
Add(u,v);
Add(v,u);
}
dfs();
} void work() {
char cmd;
int a,b,c;
for(int i=;i<=m;i++) {
for(cmd=gc;cmd!='C' && cmd!='Q';cmd=gc);
gt(a);gt(b);
newroot(a);
access(b);
splay(b);
if(cmd=='C') {
gt(c);
add_tag(b,c);
}else {
pt(da[b].num);
pc('\n');
}
}
}
int main() {
#ifdef DEBUG
freopen("paint.in","r",stdin);
freopen("paint.out","w",stdout);
#endif
fread(in,,D,stdin); init();
work(); return printf(out),;
}

bzoj2243 sdoi2011 染色 paint的更多相关文章

  1. BZOJ2243 SDOI2011 染色 【树链剖分】

    BZOJ2243 SDOI2011 染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色 ...

  2. bzoj2243[SDOI2011]染色 树链剖分+线段树

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

  3. [bzoj2243][SDOI2011]染色

    Description 给定一棵有$n$个节点的无根树和$m$个操作,操作有$2$类: 1.将节点$a$到节点$b$路径上所有点都染成颜色$c$; 2.询问节点$a$到节点$b$路径上的颜色段数量(连 ...

  4. BZOJ2243[SDOI2011]染色——树链剖分+线段树

    题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221 ...

  5. [BZOJ2243][SDOI2011]染色 解题报告|树链剖分

    Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...

  6. BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)

    题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...

  7. BZOJ2243: [SDOI2011]染色(树链剖分/LCT)

    Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如 ...

  8. bzoj2243: [SDOI2011]染色--线段树+树链剖分

    此题代码量较大..但是打起来很爽 原本不用lca做一直wa不知道为什么.. 后来改lca重打了一遍= =结果一遍就AC了orz 题目比较裸,也挺容易打,主要是因为思路可以比较清晰 另:加读入优化比没加 ...

  9. BZOJ2243——[SDOI2011]染色

    1.题目大意:给个树,然后树上每个点都有颜色,然后会有路径的修改,有个询问,询问一条路径上的颜色分成了几段 2.分析:首先这个修改是树剖可以做的,对吧,但是这个分成了几段怎么搞呢,我们的树剖的不是要建 ...

随机推荐

  1. 读懂IL代码(一)

    以前刚开始学C#的时候,总有高手跟我说,去了解一下IL代码吧,看懂了你能更加清楚的知道你写出来的代码是如何运行互相调用的,可是那时候没去看,后来补的,其实感觉也不晚.刚开始看IL代码的时候,感觉非常吃 ...

  2. 数组操作- reverse sort each 操作

    reverse reverse 操作符会读取列表(也可能来自数组),并按相反的次序返回该列表. .. ; @barney = reverse(@fred); # 得10,9,8,7,6 .. ; # ...

  3. js作用域与作用域链

    一直对Js的作用域有点迷糊,今天偶然读到JavaScript权威指南,立马被吸引住了,写的真不错.我看的是第六版本,相当的厚,大概1000多页,Js博大精深,要熟悉精通需要大毅力大功夫. 一:函数作用 ...

  4. 如何使一个input文本框随其中内容而变化长度。

    第一:<input type="text" onkeydown="this.onkeyup();" onkeyup="this.size=(th ...

  5. ComboBoxEdit

    1.  如何使其不可编辑 TextEditStyle 设置为:DisableTextEditor 2.  如何设置鼠标为手形 Cursor 设置为:Hand

  6. 分页插件jquery.simplePagination.js使用

    利用ecshop后台,利用插件更改分页显示样式遇到的问题,由于是利用Ajax获取数据进行页面数据更新?所以出现了以下情况: 初始化页面前 : 分页更新后: 点击后出现了分页插件内容消失, 原因:分页一 ...

  7. 响应式设计的5个CSS实用技巧

    正如我在教程响应式Web设计三步走当中所讲的,响应式的Web设计其实并不难,但是要让元素在布局切换时能够平滑过渡就比较考验技巧了.现在我分享在编码时常用的五个CSS技巧并举例说明.这些技巧都是使用简单 ...

  8. width:100%缩小窗口时背景图片出现空白bug

    页面容器(#wrap)与页面头部(#header )为100%宽度.而内容的容器(#page)为固定宽度960px.浏览窗口缩小而小于内容层宽度时会产生宽度理解上的差异.如下图所示窗口宽度大于内容层宽 ...

  9. google zxing 二维码扫描(android client分析)

    一.总体架构 二.架构分析 1. com.google.zxing.client.android AmbientLightManager 环境光线管理 Detects ambient light an ...

  10. bzoj2180: 最小直径生成树

    Description 输入一个无向图G=(V,E),W(a,b)表示边(a,b)之间的长度,求一棵生成树T,使得T的直径最小.树的直径即树的最长链,即树上距离最远的两点之间路径长度. Input 输 ...