[bzoj2243][SDOI2011]染色

来自FallDream 的博客,未经允许,请勿转载,谢谢qaq


给定一棵有n个节点的无根树和m个操作,操作有2类:

1、将节点a到节点b路径上所有点都染成颜色c

2、询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”、“222”和“1”。

请你写一个程序依次完成这m个操作。

n,m<=100000

 

题解:颜色信息考虑维护区间左右端点和答案,明显可以合并,所以考虑树剖之后线段树维护。复杂度$O(nlog^{2}n)$

#include<iostream>
#include<cstdio>
#define pa pair<int,int>
#define mp(x,y) make_pair(x,y)
#define MN 100000
using namespace std;
inline int read()
{int x = 0 , f = 1; char ch = getchar();while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f;
}struct data{int l,r,x;data(int _x=0):l(_x),r(_x){x=1;}data(int x,int y,int z):l(x),r(y),x(z){}data operator+(data b){return data(l,b.r,x+b.x-(r==b.l));}data operator~(){return data(r,l,x);}
};
struct node{int l,r,val;bool tag;data x;}T[MN*4+6];
struct edge{int to,next;}e[MN*2+5];
int n,m,head[MN+5],a[MN+5],cnt=0,fa[MN+5],top[MN+5],mx[MN+5],size[MN+5],dfn[MN+5],dn=0,p[MN+5],dep[MN+5];
pa q1[MN+5],q2[MN+5];int top1,top2;
char op[5];
inline void ins(int f,int t)
{e[++cnt]=(edge){t,head[f]};head[f]=cnt;e[++cnt]=(edge){f,head[t]};head[t]=cnt;
}void dfs1(int x,int f)
{fa[x]=f;size[x]=1;mx[x]=0;for(int i=head[x];i;i=e[i].next)if(e[i].to!=f){dep[e[i].to]=dep[x]+1;dfs1(e[i].to,x);size[x]+=size[e[i].to];if(size[e[i].to]>size[mx[x]]) mx[x]=e[i].to;}
}void dfs2(int x,int tp)
{top[x]=tp;p[dfn[x]=++dn]=x;if(mx[x]) dfs2(mx[x],tp);for(int i=head[x];i;i=e[i].next)if(e[i].to!=fa[x]&&e[i].to!=mx[x])dfs2(e[i].to,e[i].to);
}void pushdown(int x)
{int l=x<<1,r=x<<1|1;T[l].x=T[r].x=data(T[x].val);T[l].val=T[r].val=T[x].val;T[x].val=0;T[l].tag=T[r].tag=1;T[x].tag=0;
}void build(int x,int l,int r)
{if((T[x].l=l)==(T[x].r=r)){T[x].x=data(a[p[l]]);return;}int mid=l+r>>1;build(x<<1,l,mid);build(x<<1|1,mid+1,r);T[x].x=T[x<<1].x+T[x<<1|1].x;
}void renew(int x,int l,int r,int c)
{if(T[x].l==l&&T[x].r==r){T[x].x=data(c);T[x].val=c;T[x].tag=1;return;}if(T[x].tag) pushdown(x);int mid=T[x].l+T[x].r>>1;if(r<=mid) renew(x<<1,l,r,c);else if(l>mid) renew(x<<1|1,l,r,c);else renew(x<<1,l,mid,c),renew(x<<1|1,mid+1,r,c);T[x].x=T[x<<1].x+T[x<<1|1].x;
}void Renew(int y,int x,int c)
{while(top[x]!=top[y]){if(dep[top[x]]<dep[top[y]]) swap(x,y);renew(1,dfn[top[x]],dfn[x],c);x=fa[top[x]];}renew(1,min(dfn[y],dfn[x]),max(dfn[x],dfn[y]),c);
}data query(int x,int l,int r)
{if(T[x].l==l&&T[x].r==r) return T[x].x;if(T[x].tag) pushdown(x);int mid=T[x].l+T[x].r>>1;if(r<=mid) return query(x<<1,l,r);else if(l>mid) return query(x<<1|1,l,r);else return query(x<<1,l,mid)+query(x<<1|1,mid+1,r);
}int Query(int x,int y)
{top1=top2=0;data ans;bool flag=true;while(top[x]!=top[y]){if(dep[top[x]]>dep[top[y]])    {q1[++top1]=mp(dfn[top[x]],dfn[x]);x=fa[top[x]];}else{q2[++top2]=mp(dfn[top[y]],dfn[y]);y=fa[top[y]];}}    for(int i=1;i<=top1;i++) ans=flag?(flag=false,~query(1,q1[i].first,q1[i].second)):(ans+~query(1,q1[i].first,q1[i].second));if(dep[x]<dep[y]) ans=flag?(flag=false,query(1,dfn[x],dfn[y])):(ans+query(1,dfn[x],dfn[y]));else ans=flag?(flag=false,~query(1,dfn[y],dfn[x])):(ans+~query(1,dfn[y],dfn[x]));for(int i=top2;i;i--) ans=ans+query(1,q2[i].first,q2[i].second);return ans.x;
}int main()
{n=read();m=read();for(int i=1;i<=n;i++ )a[i]=read();for(int i=1;i<n;i++) ins(read(),read());dfs1(1,0);dfs2(1,1);build(1,1,n);for(int i=1;i<=m;i++){scanf("%s",op+1);int x=read(),y=read();if(op[1]=='Q') printf("%d\n",Query(x,y));else Renew(x,y,read());}return 0;
}

 

转载于:https://www.cnblogs.com/FallDream/p/bzoj2243.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/252922.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux学习笔记——例说makefile 增加宏定义

从学习C语言开始就慢慢开始接触makefile&#xff0c;查阅了很多的makefile的资料但总感觉没有真正掌握makefile&#xff0c;如果自己动手写一个makefile总觉得非常吃力。所以特意借助博客总结makefile的相关知识&#xff0c;通过例子说明makefile的具体用法。 例说makefile…

Android基本组件是什么?

1、ImageView继承View组件,不单单用于显示图片,用 XML代码 编写的Drawable也可以显示出来。其中的XML属性 android:scaleType(设置图片如何缩放或移动以适应ImageView的大小) 有很多的属性值,如:matrix(使用矩形方式进行缩放)fitXY(对图片横向纵向缩放)center(图片放在ImageVie…

Java 运算符及优先级

运算符 分割符&#xff1a;  ,  ;  []  ()算数运算符&#xff1a;    -  *  /  %    --关系运算符&#xff1a;  >  <  >  <    !逻辑运算符&#xff1a;  !  &  |  ^  &&  ||赋值运算符&#xff1a; …

array sort - 2 : quick sort

递归实现&#xff1a; #include <stdio.h>int arr[10] {3, 2, 4, 1, 9, 7, 5, 6, 0, 8};void print_array(){ int i 0; for (i 0; i < 10; i) printf("arr[%d]:%d ", i, arr[i]); printf("\n");}void swap(int *i, int *j){ …

Linux C 读取文件夹下所有文件(包括子文件夹)的文件名

本文&#xff1a;http://www.cnblogs.com/xudong-bupt/p/3504442.html Linux C 下面读取文件夹要用到结构体struct dirent&#xff0c;在头#include <dirent.h>中&#xff0c;如下&#xff1a; #include <dirent.h> struct dirent {long d_ino; /* inode number 索…

报表工具实现单据套打

【摘要】 单据套打再也不用手动测量&#xff0c;反复调试了&#xff0c;报表工具实现单据套打&#xff0c;去乾学院看个究竟&#xff1a;报表工具实现单据套打!实际项目开发中&#xff0c;很多情况会涉及到单据的打印。即在一张印刷好的空白单据上&#xff0c;准确无误地打印上…

每隔10秒钟打印一个“Helloworld”

/*** 每隔10秒钟打印一个“Helloworld”*/ public class Test03 {public static void main(String[] args) throws InterruptedException {ThreadImp threadImp new ThreadImp();Thread thread1 new Thread(threadImp);thread1.start();} }class ThreadImp extends Thread {p…

C++ STL 优先队列

//优先队列//Priority_queue //STL#include<iostream>#include<cstdio>#include<cstdlib>#include<queue>using namespace std;struct cmp{ bool operator() (const int a,const int b) const{//用const定义的a,b是包裹着变量外衣的常数&#xff0c;不…

GDB调试core文件样例(如何定位Segment fault)

core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump. (Linux中如果内存越界会收到SIGSEGV信号&#xff0c;然后就会core dump) 在程序运行的过程中&#xff0c;有的时候我们会遇到Segment fa…

管理信息系统的开发与管理

{% extendsmuban.html %} {% block head %}输入{% endblock %} {% block main %} <div><div class"form-group"><label for"question">标题</label><textarea class"form-control" cols"50" rows"2&q…

python11-28笔记(1.6-1.7)

1.6 多类型传值和冗余参数多类型传值&#xff1a;比如def fun(x,y)&#xff0c;定义2个形参定义一个元组t(1,2),如果把元组当做实参传入到函数中&#xff0c;会报错 如何将元组当做不同类型的参数传入到函数中fun(t) 代表传入的是元组或者这样调用fun((1,2))注意实参的个数要和…

session机制详解以及session的相关应用

session是web开发里一个重要的概念&#xff0c;在大多数web应用里session都是被当做现成的东西&#xff0c;拿来就直接用&#xff0c;但是一些复杂的web应用里能拿来用的session已经满足不了实际的需求&#xff0c;当碰到这样的情况时候我们需要更加深入的理解session的机制&am…

(转)Shell中获取字符串长度的七种方法

Shell中获取字符串长度的七种方法 原文&#xff1a;http://blog.csdn.net/jerry_1126/article/details/51835119 求字符串操作在shell脚本中很常用&#xff0c;下面归纳、汇总了求字符串的几种可能方法: 【方法一】:利用${#str}来获取字符串的长度 【方法二】:利用awk的length方…

linux下用core和gdb查询出现段错误的地方

有些时候我们在一段C代码的时候&#xff0c;由于对一个非法内存进行了操作&#xff0c;在程序运行的过程中&#xff0c;出现了"段错误"。呵呵&#xff0c;这种问题我想很多人会经常遇到。遇到这种问题是非常无语的&#xff0c;只是提示了"段错误"&#xff…

第一篇-Html标签中head标签,body标签中input系列,textarea和select标签

第十四周课程&#xff08;1-12章节&#xff09; HTML 裸体 CSS 穿华丽衣服 Javascript 动起来 一 HTML &#xff08;20个标签&#xff09; 1.我们的浏览器是socket客户端 2.一套规则&#xff0c;浏览器认识的规则 3.开发者&#xff1a; 学习html规则 开发后台程序&#xff1a…

opencv3.2.0 Cmake 3.8.0 + tdm-gcc-5.1.0-3

实测 tdm-gcc-5.1.0-3 tdm32-1 32位版本无法正确编译Opencv 3.2.0 会遇到诸多编译问题 解决办法 使用tdm-gcc-5.1.0-2 tdm64-1 64位版本转载于:https://www.cnblogs.com/fundou/p/6710209.html

什么是商品属性

一、什么是商品属性&#xff1a; Definition of Product Attributes A product attribute is a characteristic that defines a particular product and will affect a consumers purchase decision. Product attributes can be tangible (or physical in nature) or intangibl…

linux用户管理(1)----创建用户(adduser和useradd)和删除用户(userdel)

arm linux的系统用户管理&#xff1a; 1、删除root用户&#xff1a;deluser root2、删除tt用户:deluser tt3、建立root用户&#xff1a;adduser root4、修改用户密码&#xff1a;登录相应的用户后&#xff0c;用passwd来修改密码4、linux用户和密码的管理&#xff08;ftp&#…

前端性能优化之图像优化原理

前端性能优化中&#xff0c;图像的优化是非常重要的一环&#xff0c;为什么要说图像的优化呢&#xff0c;而不是我们常见的图片优化&#xff1f;因为这里的图像包括矢量图和位图&#xff0c;我们常说的图片优化是指位图的优化。这篇文章转载至奇舞周刊&#xff0c;大佬总结的非…

Lua开发学习4-普通循环和迭代器循环

说句实话&#xff0c;每当看到Lua代码&#xff0c;我都感觉是半个SQL代码&#xff0c;写起来还是感觉有点恐怖。 while循环&#xff1a; 与C#的while循环类似&#xff0c;没有什么好说的&#xff1b; --------Lua的while循环 while(condition)dostatementsend For循环 exp1为起…