BZOJ 3083: 遥远的国度(树链剖分+DFS序)
可以很显而易见的看出,修改就是树链剖分,而询问就是在dfs出的线段树里查询最小值,但由于这道题会修改根节点,所以在查询的时候需判断x是否为root的祖先,如果不是就直接做,是的话应该查询从1-st[y]-1 ed[y]+1 -- n 的最小值,其中y是root的祖先,x的儿子
PS:好久没做题,线段树都查了好久QAQ,还是没查出错来,最后只能cheat一个程序了QAQ
CODE:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 100010
#define maxm 200020
typedef long long ll ;
struct edges{
int to,next;
}edge[maxm];
int next[maxn],l,n,m;
int addedge(int x,int y){
edge[++l]=(edges){y,next[x]};next[x]=l;
edge[++l]=(edges){x,next[y]};next[y]=l;
return 0;
}
ll _min(ll x,ll y){
if (x==0) return y;
if (y==0) return x;
return min(x,y);
}
int dep[maxn],fa[maxn],sum[maxn],ch[maxn],pre[maxn],pos[maxn],add[maxn],lef[maxn],righ[maxn];
int cl;
bool b[maxn];
int dfs(int u){
dep[u]=dep[fa[u]]+1;
sum[u]=1;b[u]=1;
for (int i=next[u];i;i=edge[i].next)
if (!b[edge[i].to]){
fa[edge[i].to]=u;
dfs(edge[i].to);
sum[u]+=sum[edge[i].to];
ch[u]=sum[edge[i].to]>sum[ch[u]]?edge[i].to:ch[u];
}
return 0;
}
int heavy(int u,bool bo){
cl++;
pos[add[cl]=u]=cl;
b[u]=1;lef[u]=cl;
if (bo) pre[u]=u;
else pre[u]=pre[fa[u]];
if (ch[u]) heavy(ch[u],0);
for (int i=next[u];i;i=edge[i].next)
if (!b[edge[i].to])
heavy(edge[i].to,1);
righ[u]=cl;
return 0;
}
struct TREE{
int l,r;ll x;bool lazy;
}t[maxn*8];
ll s[maxn];
int buildtree(int x,int l,int r){
t[x].l=l;t[x].r=r;
if (l==r) {t[x].x=s[add[l]];return 0;}
buildtree(x<<1,l,(l+r)>>1);
buildtree((x<<1)+1,((l+r)>>1)+1,r);
t[x].x=_min(t[x<<1].x,t[(x<<1)+1].x);
return 0;
}
int pushdown(int x){
if (t[x].lazy) {
t[x<<1].x=t[(x<<1)+1].x=t[x].x;
t[x<<1].lazy=t[(x<<1)+1].lazy=1;
t[x].lazy=0;
}
return 0;
}
ll cha(int x,int x1,int y1){
int l=t[x].l,r=t[x].r;
if (l>y1||r<x1) return 0;
if (l==r) return (t[x].x);
if (l>=x1&&r<=y1) return t[x].x;
pushdown(x);
return _min(cha(x<<1,x1,y1),cha((x<<1)+1,x1,y1));
}
int gai(int x,ll y,int x1,int y1){
int l=t[x].l,r=t[x].r;
if (l>y1||r<x1) return 0;
if (l==r) {t[x].x=y;return 0;}
if (l>=x1&&r<=y1) {t[x].lazy=1;t[x].x=y;return 0;}
pushdown(x);
gai(x<<1,y,x1,y1);gai((x<<1)+1,y,x1,y1);
t[x].x=_min(t[x<<1].x,t[(x<<1)+1].x);
return 0;
}
int change(int l,int r,ll x){
for (;;){
if (pre[l]==pre[r]) {
if (dep[l]>dep[r]) swap(l,r);
gai(1,x,pos[l],pos[r]);
return 0;
}else{
if (dep[pre[l]]<dep[pre[r]]) swap(l,r);
gai(1,x,pos[pre[l]],pos[l]);
l=fa[pre[l]];
}
}
return 0;
}
int root,tem;
bool check(int x){
int y=root;
while (fa[y]!=0){
if (fa[y]==x) {tem=y;return 1;}
if (dep[fa[y]]<dep[x]) return 0;
if (pre[fa[y]]==pre[x]) {tem=ch[x];return 1;}
y=pre[fa[y]];
}
return 0;
}
ll query(int x){
if (!check(x))return (cha(1,lef[x],righ[x]));
else return (_min(cha(1,1,lef[tem]-1),cha(1,righ[tem]+1,n)));
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<n;i++) {
int x,y;
scanf("%d%d",&x,&y);
addedge(x,y);
}
for (int i=1;i<=n;i++) scanf("%lld",s+i);
memset(b,0,sizeof(b));
dfs(1);
memset(b,0,sizeof(b));
heavy(1,1);
buildtree(1,1,n);
scanf("%d",&root);
while (m--){
int opt,l,r;ll x;
scanf("%d",&opt);
if (opt==1) scanf("%d",&root);
if (opt==2) {
scanf("%d%d%lld",&l,&r,&x);
change(l,r,x);
}
if (opt==3){
scanf("%d",&l);
printf("%lld\n",query(l));
}
}
return 0;
}
BZOJ 3083: 遥远的国度(树链剖分+DFS序)的更多相关文章
- BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 Solved: 795[Submit][Status][Discu ...
- BZOJ 3083 遥远的国度 树链剖分
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 797 Solved: 181[Submit][Status] Descrip ...
- BZOJ 3083 遥远的国度(树链剖分+LCA)
Description 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要z ...
- BZOJ 3083 遥远的国度 树链剖分+线段树
有换根的树链剖分的裸题. 在换根的时候注意讨论. 注意数据范围要开unsigned int或longlong #include<iostream> #include<cstdio&g ...
- bzoj 3083 遥远的国度 —— 树链剖分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 换根后路径还是不变,子树分类讨论一下,树剖后线段树维护即可. 代码如下: #inclu ...
- bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了…… O( nlog ...
- BZOJ 3083 遥远的国度 树链剖分+脑子
唉..又调了半天QWQ..为何读入挂了.....莫非读入是反着的????据ywy学长所言如是...OvO震惊 这啥骚题啊...还要换根...不过清明讲过...(然鹅我现在才做... 先随便选个点(比如 ...
- [BZOJ - 2819] Nim 【树链剖分 / DFS序】
题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...
- 树链剖分&dfs序
树上问题 很多处理区间的问题(像是RMQ,区间修改).可以用线段树,树状数组,ST表这些数据结构来维护.但是如果将这些问题挪到了树上,就不能直接用这些数据结构来处理了.这时就用到了dfs序和树链剖分. ...
随机推荐
- 可持久化Trie树初步
可持久化Trie树和可持久化线段树很像,依次插入信息,通过减法来进行历史版本查询. 2015年11月27日 bzoj3261 最大异或和 我们需要计算 a[p] xor a[p+1] xor ... ...
- Git提交过程的一些问题
参考:http://www.cnblogs.com/sinojelly/archive/2011/08/07/2130172.html 提交冲突,无法提交到github git pull origin ...
- discuz开发学习
2014年3月24日 10:36:10 遇到一个问题,discuz 缓存的样式,没有自动生成.后来去后台 进行操作才有效. 解决了之前的遇到的 首页没有套用样式的问题. 现在的问题是 模版的扩展图片 ...
- java--面向对象编程
instanceof的用法 静态绑定,即早期绑定,首先找父类 动态绑定,即运行时绑定,new谁找谁 Object o1 = null; //正确的语法,null也是一种特殊的引用数据类型 object ...
- java系列--EL和JSTL
一.EL表达式语言 构成:${变量} 功能:可以从范围对象直接取值 默认为requestScope 如果访问的属性不存在,EL返回值为null,但在JSP页面中显示空字符串不显示 EL表达式可以出现的 ...
- OpenCV点滴2
明天回家了-- 昨天去见了老师,去之前告诉自己不要紧张,去了后还是紧张了,语无伦次,很没礼貌--(不敢看老师的眼睛) 刚才妈打电话说让我早点回去,不知道为什么,在空荡荡的宿舍里听到妈的声音,眼泪会夺眶 ...
- IM 之 融云
官方网站:http://www.rongcloud.cn 官方开发文档:http://www.rongcloud.cn/docs/ IM 融云 之 开发基础概念 IM 融云 之 通讯能力库API IM ...
- Spring mvc基本原理
http://blog.csdn.net/xtu_xiaoxin/article/details/8796499 http://www.cnblogs.com/wawlian/archive/2012 ...
- myeclipse 2014破解
开始安装的时候已经进行了破解,不知道为什么还是会出现问题,按照下面说的才可以了: http://blog.sina.com.cn/s/blog_7f5862570101oxyv.html
- 计算数据库中30天以内,30-60天,60-90天,90天以外的数据的个数(用sql实现)
30天以内:select count(*) from TB where datediff(day,字段名,getdate()) between 0 and 3030-60天:select count( ...