题目描述

输入输出格式

输入格式:

输出格式:

对于每个询问操作,输出一行答案。

输入输出样例

输入样例#1:

6 5
2 2 1 2 1 1
1 2
1 3
2 4
2 5
2 6
Q 3 5
C 2 1 1
Q 3 5
C 5 1 2
Q 3 5
输出样例#1:

3
1
2

说明

思路:

  树剖+线段树维护区间颜色数量

来,上代码:

#include <cstdio>
#include <iostream>
#include <algorithm> #define maxn 200001 using namespace std; struct TreeNodeType {
int l,r,dis,lc,rc,flag,mid;
};
struct TreeNodeType tree[maxn<<]; struct EdgeType {
int to,next;
};
struct EdgeType edge[maxn<<]; int n,m,if_z,dis[maxn],flag[maxn],dis_[maxn];
int size[maxn],head[maxn],deep[maxn],f[maxn];
int cnt,tot,num,belong[maxn]; char Cget; inline void read_int(int &now)
{
now=,if_z=,Cget=getchar();
while(Cget>''||Cget<'')
{
if(Cget=='-') if_z=-;
Cget=getchar();
}
while(Cget>=''&&Cget<='')
{
now=now*+Cget-'';
Cget=getchar();
}
now*=if_z;
} inline void edge_add(int from,int to)
{
edge[++num].to=from,edge[num].next=head[to],head[to]=num;
edge[++num].to=to,edge[num].next=head[from],head[from]=num;
} void search(int now,int fa)
{
int pos=cnt++;
deep[now]=deep[fa]+,f[now]=fa;
for(int i=head[now];i;i=edge[i].next)
{
if(edge[i].to==fa) continue;
search(edge[i].to,now);
}
size[now]=cnt-pos;
} void search_(int now,int chain)
{
belong[now]=chain,flag[now]=++cnt;
dis_[flag[now]]=dis[now];
int pos=;
for(int i=head[now];i;i=edge[i].next)
{
if(edge[i].to==f[now]) continue;
if(size[edge[i].to]>size[pos]) pos=edge[i].to;
}
if(pos!=) search_(pos,chain);
else return ;
for(int i=head[now];i;i=edge[i].next)
{
if(edge[i].to==f[now]||edge[i].to==pos) continue;
search_(edge[i].to,edge[i].to);
}
} inline void tree_up(int now)
{
if(tree[now<<].rc==tree[now<<|].lc)
{
tree[now].dis=tree[now<<].dis+tree[now<<|].dis-;
}
else
{
tree[now].dis=tree[now<<].dis+tree[now<<|].dis;
}
tree[now].lc=tree[now<<].lc,tree[now].rc=tree[now<<|].rc;
} inline void tree_down(int now)
{
if(tree[now].l==tree[now].r) return ;
tree[now<<].dis=,tree[now<<|].dis=;
tree[now<<].lc=tree[now<<].rc=tree[now].flag;
tree[now<<|].lc=tree[now<<|].rc=tree[now].flag;
tree[now<<].flag=tree[now<<|].flag=tree[now].flag;
tree[now].flag=;
} void tree_build(int now,int l,int r)
{
tree[now].l=l,tree[now].r=r;
if(l==r)
{
tree[now].lc=dis_[++cnt];
tree[now].rc=tree[now].lc;
tree[now].dis=;
return ;
}
tree[now].mid=(l+r)>>;
tree_build(now<<,l,tree[now].mid);
tree_build(now<<|,tree[now].mid+,r);
tree_up(now);
} void tree_change(int now,int l,int r,int x)
{
if(tree[now].l==l&&tree[now].r==r)
{
tree[now].dis=,tree[now].flag=x;
tree[now].lc=tree[now].rc=x;
return ;
}
if(tree[now].flag) tree_down(now);
if(l>tree[now].mid) tree_change(now<<|,l,r,x);
else if(r<=tree[now].mid) tree_change(now<<,l,r,x);
else
{
tree_change(now<<,l,tree[now].mid,x);
tree_change(now<<|,tree[now].mid+,r,x);
}
tree_up(now);
} int tree_query(int now,int l,int r)
{
if(tree[now].l==l&&tree[now].r==r)
{
return tree[now].dis;
}
if(tree[now].flag) tree_down(now);
tree_up(now);
if(l>tree[now].mid) return tree_query(now<<|,l,r);
else if(r<=tree[now].mid) return tree_query(now<<,l,r);
else
{
int ld=tree_query(now<<,l,tree[now].mid);
int rd=tree_query(now<<|,tree[now].mid+,r);
if(tree[now<<].rc==tree[now<<|].lc) return ld+rd-;
else return ld+rd;
}
} int tree_query_color(int now,int to)
{
if(tree[now].l==tree[now].r&&tree[now].l==to)
{
return tree[now].lc;
}
if(tree[now].flag) tree_down(now);
tree_up(now);
if(to>tree[now].mid) return tree_query_color(now<<|,to);
else return tree_query_color(now<<,to);
} inline void solve_change(int x,int y,int z)
{
while(belong[x]!=belong[y])
{
if(deep[belong[x]]<deep[belong[y]]) swap(x,y);
tree_change(,flag[belong[x]],flag[x],z);
x=f[belong[x]];
}
tree_change(,min(flag[x],flag[y]),max(flag[x],flag[y]),z);
} inline int solve_query(int x,int y)
{
int ans=;
while(belong[x]!=belong[y])
{
if(deep[belong[x]]<deep[belong[y]]) swap(x,y);
ans+=tree_query(,flag[belong[x]],flag[x]);
if(tree_query_color(,flag[belong[x]])==tree_query_color(,flag[f[belong[x]]])) ans--;
x=f[belong[x]];
}
ans+=tree_query(,min(flag[x],flag[y]),max(flag[x],flag[y]));
return ans;
} int main()
{
read_int(n),read_int(m);
for(int i=;i<=n;i++) read_int(dis[i]);
int from,to,pos;
for(int i=;i<n;i++)
{
read_int(from),read_int(to);
edge_add(from,to);
}
search(,),cnt=,search_(,),cnt=,tree_build(,,n);
char type;
for(int i=;i<=m;i++)
{
cin>>type;
if(type=='C')
{
read_int(from),read_int(to),read_int(pos);
solve_change(from,to,pos);
}
else
{
read_int(from),read_int(to);
printf("%d\n",solve_query(from,to));
}
}
return ;
}

AC日记——[SDOI2011]染色 洛谷 P2486的更多相关文章

  1. AC日记——[SDOI2011]消耗战 洛谷 P2495

    [SDOI2011]消耗战 思路: 建虚树走树形dp: 代码: #include <bits/stdc++.h> using namespace std; #define INF 1e17 ...

  2. AC日记——寻找道路 洛谷 P2296

    题目描述 在有向图G 中,每条边的长度均为1 ,现给定起点和终点,请你在图中找一条从起点到终点的路径,该路径满足以下条件: 1 .路径上的所有点的出边所指向的点都直接或间接与终点连通. 2 .在满足条 ...

  3. AC日记——铺地毯 洛谷 P1003(水水水水水~)

    题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...

  4. AC日记——过河卒 洛谷 1002

    题目描述 棋盘上A点有一个过河卒,需要走到目标B点.卒行走的规则:可以向下.或者向右.同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点.因此称之为“马拦过河卒”. ...

  5. AC日记——[SDOI2017]相关分析 洛谷 P3707

    [SDOI2017]相关分析 思路: 裸线段树: (玄学ac): 代码: #include <bits/stdc++.h> using namespace std; #define max ...

  6. AC日记——丢瓶盖 洛谷 P1316

    题目描述 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢? 输入输出 ...

  7. AC日记——滑动窗口 洛谷 P1886

    题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...

  8. AC日记——挤牛奶 洛谷 P1204

    题目描述 三个农民每天清晨5点起床,然后去牛棚给3头牛挤奶.第一个农民在300秒(从5点开始计时)给他的牛挤奶,一直到1000秒.第二个农民在700秒开始,在 1200秒结束.第三个农民在1500秒开 ...

  9. AC日记——导弹拦截 洛谷 P1020 (dp+模拟)

    题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...

随机推荐

  1. 谈谈你对Hibernate的理解

    答: 1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象.建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样,本质上都是要得到一 ...

  2. 多本Python极速入门最佳书籍,不可错过的Python学习资料!

    Python作为现在很热门的一门编程语言,介于Python的友好,许多的初学者都将其作为首选,为了帮助大家更好的学习Python,我筛选了2年内优秀的python书籍,个别经典的书籍扩展到5年内.   ...

  3. python寻找模块的路径顺序

    >>> import sys >>> sys.path ['', '/Library/Frameworks/Python.framework/Versions/3. ...

  4. Eclipse设置C++自动补全变量名快捷键

    用快捷键:Alt+/ 要是还是有些场合不能提示,按照下列步骤 Window-Preferences-c/c++-Editor-Content Assist-Advanced 将未勾选的全部勾选

  5. Ice cream samples Gym - 101670G 滑动扫描

    题目:题目链接 思路:比赛中读错了题,题目要求选一个连续区间,却读成了随便选取几个柜台,英语要好好学啊,读懂题就很简单了,扫一遍就出结果了 AC代码: #include <iostream> ...

  6. CodeForce:732B-Cormen — The Best Friend Of a Man

    传送门:http://codeforces.com/problemset/problem/732/B Cormen - The Best Friend Of a Man time limit per ...

  7. The 2018 ACM-ICPC Chinese Collegiate Programming Contest Fight Against Monsters

    #include <iostream> #include <cstdio> #include <cstring> #include <string> # ...

  8. selenium2常用API介绍

    我们模拟web操作都是基于元素来操作的,我们首先要先确定元素,然后这个元素下对应的方法就可以看WebElement的方法. 1.点击操作 WebElement button=driver.findEl ...

  9. Django one

    WEB-Django: Http协议: http协议:超文本传输协议,基于TCP/IP通信协议来传递数据 特点: 1.灵活:允许传输任意类型的数据对象.正在传输的类型有Content-Type标记 2 ...

  10. wordpress 获取站点的所有链接

    <?php include "wp-load.php"; $posts = new WP_Query('post_type=any&posts_per_page=-1 ...