B20J_3231_[SDOI2014]旅行_树链剖分+线段树
B20J_3231_[SDOI2014]旅行_树链剖分+线段树
题意:
S国有N个城市,编号从1到N。城市间用N-1条双向道路连接,城市信仰不同的宗教,为了方便,我们用不同的正整数代表各种宗教。
S国的居民常常旅行,只在信仰和他们相同的城市留宿。当然旅程的终点也是信仰与他相同的城市。S国政府为每个城市标定了不同的旅行评级,旅行者们常会记下途中(包括起点和终点)留宿过的城市的评级总和或最大值。
以下几种操作:
• "CC x c":城市x的居民全体改信了c教;
• "CW x w":城市x的评级调整为w;
• "QS x y":一位旅行者从城市x出发,到城市y,并记下了途中留宿过的城市的评级总和;
• "QM x y":一位旅行者从城市x出发,到城市y,并记下了途中留宿过的城市的评级最大值。
分析:对每个宗教开一个线段树(动态开点)。CC操作时删除原来宗教所在线段树上该点的值,在新的宗教所在线段树中加入该点的值。
注意:
1.在查询时遇到一个空点要return。
2.修改时线段树上的值和本身的值都要修改
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N=100001;
int head[N],to[N<<1],nxt[N<<1],val[N],b[N],cnt;
int son[N],top[N],dep[N],fa[N],siz[N],idx[N],tot,cet;
int tree[N],lson[N*20],rson[N*20],d[N*20],m[N*20];
void add(int u,int v)
{
to[++cnt]=v;
nxt[cnt]=head[u];
head[u]=cnt;
}
int n,q;
char s[10];
void dfs1(int x,int y)
{
fa[x]=y;
siz[x]=1;
dep[x]=dep[y]+1;
for(int i=head[x];i;i=nxt[i])
{
if(to[i]!=y)
{
dfs1(to[i],x);
siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]])
{
son[x]=to[i];
}
}
}
}
void dfs2(int x,int t)
{
top[x]=t;
idx[x]=++tot;
if(son[x])dfs2(son[x],t);
for(int i=head[x];i;i=nxt[i])
{
if(to[i]!=fa[x]&&to[i]!=son[x])
{
dfs2(to[i],to[i]);
}
}
}
void up(int l,int r,int x,int y,int &p)
{
if(!p)p=++cet;
if(l==r)
{
d[p]=m[p]=y;
return ;
}
int mid=l+r>>1;
if(x<=mid)up(l,mid,x,y,lson[p]);
else up(mid+1,r,x,y,rson[p]);
d[p]=d[lson[p]]+d[rson[p]];
m[p]=max(m[lson[p]],m[rson[p]]);
}
int qsum(int l,int r,int x,int y,int &p)
{
if(p==0)return 0;
if(x<=l&&r<=y)
{
return d[p];
}
int mid=l+r>>1;
int re=0;
if(x<=mid)
{
re+=qsum(l,mid,x,y,lson[p]);
}
if(y>mid)
{
re+=qsum(mid+1,r,x,y,rson[p]);
}
return re;
}
int qmax(int l,int r,int x,int y,int &p)
{
if(p==0)return 0;
if(x<=l&&r<=y)
{
return m[p];
}
int re=0;
int mid=l+r>>1;
if(x<=mid)
{
re=max(re,qmax(l,mid,x,y,lson[p]));
}
if(y>mid)
{
re=max(re,qmax(mid+1,r,x,y,rson[p]));
}
return re;
}
int main()
{
scanf("%d%d",&n,&q);
int x,y;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&val[i],&b[i]);
}
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs1(1,0);
dfs2(1,1);
for(int i=1;i<=n;i++)
{
up(1,n,idx[i],val[i],tree[b[i]]);
}
for(int i=1;i<=q;i++)
{
scanf("%s%d%d",s,&x,&y);
if(s[1]=='C')
{
up(1,n,idx[x],0,tree[b[x]]);
b[x]=y;
up(1,n,idx[x],val[x],tree[b[x]]);
}
else if(s[1]=='S')
{
int re=0,rt=b[x];
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]])
swap(x,y);
re+=qsum(1,n,idx[top[y]],idx[y],tree[rt]);
y=fa[top[y]];
}
if(dep[x]<dep[y])swap(x,y);
re+=qsum(1,n,idx[y],idx[x],tree[rt]);
printf("%d\n",re);
}
else if(s[1]=='W')
{
up(1,n,idx[x],y,tree[b[x]]);
val[x]=y;
}
else
{
int re=0,rt=b[x];
while(top[x]!=top[y])
{
if(dep[top[x]]>dep[top[y]])
swap(x,y);
re=max(re,qmax(1,n,idx[top[y]],idx[y],tree[rt]));
y=fa[top[y]];
}
if(dep[x]<dep[y])swap(x,y);
re=max(re,qmax(1,n,idx[y],idx[x],tree[rt]));
printf("%d\n",re);
}
}
}
/***************************************************************
Problem: 2456
User: 20170105
Language: C++
Result: Accepted
Time:524 ms
Memory:42248 kb
****************************************************************/
B20J_3231_[SDOI2014]旅行_树链剖分+线段树的更多相关文章
- 洛谷P3313 [SDOI2014]旅行 题解 树链剖分+线段树动态开点
题目链接:https://www.luogu.org/problem/P3313 这道题目就是树链剖分+线段树动态开点. 然后做这道题目之前我们先来看一道不考虑树链剖分之后完全相同的线段树动态开点的题 ...
- B20J_2836_魔法树_树链剖分+线段树
B20J_2836_魔法树_树链剖分+线段树 题意: 果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u].初始时,这个果树的每个节点上都没有果子(即0个果子). Add u v d ...
- B20J_2243_[SDOI2011]染色_树链剖分+线段树
B20J_2243_[SDOI2011]染色_树链剖分+线段树 一下午净调这题了,争取晚上多做几道. 题意: 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
随机推荐
- Kubernetes如何支持有状态服务的部署?
作者:Jack47 转载请保留作者和原文出处 PS:如果喜欢我写的文章,欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. Kubernetes对无状态服务有完善的支持 ...
- log4j日志的配置
在项目开发中,记录错误日志方便调试.便于发现系统运行过程中的错误.便于后期分析, 在java中,记录日志有很多种方式,比如说log4j log4j需要导入的包: commons-loggin.jar ...
- 登录以及发送微信消息itchat 库
项目地址点这里 itchat itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单. 使用不到三十行的代码,你就可以完成一个能够处理所有信息的微信机器人. 当然,该api的 ...
- Flask框架之 - 简易静态网站 !
网站截图: Python源代码如下: # coding=utf-8 from flask import Flask,render_template app = Flask(__name__) @app ...
- 关于django migrations的使用
django 1.8之后推出的migrations机制使django的数据模式管理更方便容易,现在简单谈谈他的机制和一些问题的解决方法: 1.谈谈机制:migrations机制有两个指令,第一个是ma ...
- jsp文件放在webcontent子目录下提交表单给servlet报404错误解决办法
新版的web项目已经不需要配置web.xml了,并且eclipse neon版本里面新建web项目时候,默认不会生成web.xml文件.我们也不需要手动添加该文件,因为内部为我们提供了最新的处理方式, ...
- C# SqlBulkCopy数据批量入库
准备条件:20万+数据 界面设计使用的WPF. 没有对比就没有伤害,以下是我两种方式导入数据案例. 运行 结果对比: 首先使用一般sql语句导入,因为时间原因,我就没有等待程序执行完,但是我记录了大约 ...
- Android之淘宝商品列表长按遮罩效果
先来看看淘宝.唯品会长按商品的效果,以及简单Demo的效果: 首先分析一下场景: 长按条目时,弹出遮罩的效果遮挡在原来的条目布局上: 页面滑动或点击其他的条目,上一个正在遮罩的条目遮罩消 ...
- 浏览器渲染原理笔记 --《How Browser Work》读后总结
综述 之前使用ExtJS时遇到一个问题:为什么依次设置多个组件的可见性界面会卡顿?在了解HTML的dom操作相关内容的时候也好奇这个东西到底是怎么回事,然后尤其搞不懂CSS和Html分管样式和网页结构 ...
- 洛谷 P2725 解题报告
P2725 邮票 Stamps 题目背景 给一组 N 枚邮票的面值集合(如,{1 分,3 分})和一个上限 K -- 表示信封上能够贴 K 张邮票.计算从 1 到 M 的最大连续可贴出的邮资. 题目描 ...