洛谷 P3038 [USACO11DEC]牧草种植Grass Planting(树链剖分)


题解:仍然是无脑树剖,要注意一下边权,然而这种没有初始边权的题目其实和点权也没什么区别了
代码如下:
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lson root<<1
#define rson root<<1|1
using namespace std; struct node
{
int lazy,sum,l,r;
} tr[];
int deep[],fa[],son[],size[],id[],top[],cnt;
vector<int> g[]; void push_up(int root)
{
tr[root].sum=tr[lson].sum+tr[rson].sum;
} void push_down(int root)
{
int mid=(tr[root].l+tr[root].r)>>;
tr[lson].sum+=tr[root].lazy*(mid-tr[root].l+);
tr[lson].lazy+=tr[root].lazy;
tr[rson].sum+=tr[root].lazy*(tr[root].r-mid);
tr[rson].lazy+=tr[root].lazy;
tr[root].lazy=;
} void build(int root,int l,int r)
{
if(l==r)
{
tr[root].l=l;
tr[root].r=r;
tr[root].sum=;
return ;
}
tr[root].l=l;
tr[root].r=r;
int mid=(l+r)>>;
build(lson,l,mid);
build(rson,mid+,r);
push_up(root);
} void update(int root,int l,int r,int val)
{
if(l>r)
{
return;
}
if(l==tr[root].l&&tr[root].r==r)
{
tr[root].sum+=val*(tr[root].r-tr[root].l+);
tr[root].lazy+=val;
return ;
}
if(tr[root].lazy)
{
push_down(root);
}
int mid=(tr[root].l+tr[root].r)>>;
if(l>mid)
{
update(rson,l,r,val);
}
else
{
if(r<=mid)
{
update(lson,l,r,val);
}
else
{
update(lson,l,mid,val);
update(rson,mid+,r,val);
}
}
push_up(root);
} int query(int root,int l,int r)
{
if(l>r)
{
return ;
}
if(l==tr[root].l&&r==tr[root].r)
{
return tr[root].sum;
}
if(tr[root].lazy)
{
push_down(root);
}
int mid=(tr[root].l+tr[root].r)>>;
if(l>mid)
{
return query(rson,l,r);
}
else
{
if(r<=mid)
{
return query(lson,l,r);
}
}
return query(lson,l,mid)+query(rson,mid+,r);
} void dfs1(int now,int f,int dep)
{
deep[now]=dep;
fa[now]=f;
size[now]=;
int maxson=-;
for(int i=; i<g[now].size(); i++)
{
if(g[now][i]==f)
{
continue;
}
dfs1(g[now][i],now,dep+);
size[now]+=size[g[now][i]];
if(size[g[now][i]]>maxson)
{
son[now]=g[now][i];
maxson=size[g[now][i]];
}
}
} void dfs2(int now,int topf)
{
id[now]=++cnt;
top[now]=topf;
if(!son[now])
{
return ;
}
dfs2(son[now],topf);
for(int i=; i<g[now].size(); i++)
{
if(fa[now]==g[now][i]||son[now]==g[now][i])
{
continue;
}
dfs2(g[now][i],g[now][i]);
}
} void path_update(int x,int y,int val)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])
{
swap(x,y);
}
update(,id[top[x]],id[x],val);
x=fa[top[x]];
}
if(deep[x]>deep[y])
{
swap(x,y);
}
update(,id[x]+,id[y],val);
} int path_query(int x,int y)
{
int ans=;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]])
{
swap(x,y);
}
ans+=query(,id[top[x]],id[x]);
x=fa[top[x]];
}
if(deep[x]>deep[y])
{
swap(x,y);
}
ans+=query(,id[x]+,id[y]);
return ans;
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=; i<=n-; i++)
{
int from,to;
scanf("%d%d",&from,&to);
g[from].push_back(to);
g[to].push_back(from);
}
dfs1(,,);
dfs2(,);
build(,,n);
for(int i=; i<=m; i++)
{
int from,to;
char kd;
scanf("\n%c %d %d",&kd,&from,&to);
if(kd=='P')
{
path_update(from,to,);
}
if(kd=='Q')
{
printf("%d\n",path_query(from,to));
}
}
}
洛谷 P3038 [USACO11DEC]牧草种植Grass Planting(树链剖分)的更多相关文章
- 洛谷P3038 [USACO11DEC]牧草种植Grass Planting
题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...
- 洛谷 P3038 [USACO11DEC]牧草种植Grass Planting
题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...
- P3038 [USACO11DEC]牧草种植Grass Planting
题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...
- ⌈洛谷1505⌋⌈BZOJ2157⌋⌈国家集训队⌋旅游【树链剖分】
题目链接 [洛谷] [BZOJ] 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T ...
- AC日记——[USACO11DEC]牧草种植Grass Planting 洛谷 P3038
题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...
- 树链剖分【p3038】[USACO11DEC]牧草种植Grass Planting
表示看不太清. 概括题意 树上维护区间修改与区间和查询. 很明显树剖裸题,切掉,细节处错误T了好久 TAT 代码 #include<cstdio> #include<cstdlib& ...
- [USACO11DEC]牧草种植Grass Planting
图很丑.明显的树链剖分,需要的操作只有区间修改和区间查询.不过这里是边权,我们怎么把它转成点权呢?对于E(u,v),我们选其深度大的节点,把边权扔给它.因为这是树,所以每个点只有一个父亲,所以每个边权 ...
- 【LuoguP3038/[USACO11DEC]牧草种植Grass Planting】树链剖分+树状数组【树状数组的区间修改与区间查询】
模拟题,可以用树链剖分+线段树维护. 但是学了一个厉害的..树状数组的区间修改与区间查询.. 分割线里面的是转载的: ----------------------------------------- ...
- [USACO11DEC] Grass Planting (树链剖分)
题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...
随机推荐
- 【Flask】微型web框架flask大概介绍
Flask Flask是一个基于python的,微型web框架.之所以被称为微型是因为其核心非常简单,同时具有很强的扩展能力.它几乎不给使用者做任何技术决定. 安装flask时应该注意其必须的几个支持 ...
- STL --> deque双向队列
deque简介 deque是双向开口的连续性存储空间.虽说是连续性存储空间,但这种连续性只是表面上的,实际上它的内存是动态分配的,它在堆上分配了一块一块的动态储存区,每一块动态存储去本身是连续的,de ...
- ElasticSearch之 控制相关度原理讲解
控制相关度 相关度评分背后的理论 如何计算评分的 Lucene 使用布尔模型(Boolean model) 查找匹配文档 并主要的借鉴了 词频/逆向文档频率(term frequency/invers ...
- Vue探索历程(一)
使用vue.js原文介绍:Vue.js是一个构建数据驱动的web界面库.Vue.js的目标是通过尽可能简单的API实现响应式数据绑定和组合的视图组件.vue.js上手非常简单,先看看几个例子: 例一: ...
- 实现Windows程序的数据绑定
1.创建DataSet对象 语法: DataSet 数据集对象 =new DataSet("数据集的名称字符串"); 语法中的参数是数据集的名称字符串,可以有,也可以没有.如 ...
- Active MQ 实战(一)
1.什么是JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送 ...
- 第2次作业:stream案例分析
摘要:本次随笔是对stream软件进行一次案例分析,以个人观点分析stream为什么成功. 一.介绍产品相关信息 1.我选择的商品是stream 2.选择该产品的主要原因准要是因为自己本身喜欢玩这个平 ...
- 进程与fork()、wait()、exec函数组
进程与fork().wait().exec函数组 内容简介:本文将引入进程的基本概念:着重学习exec函数组.fork().wait()的用法:最后,我们将基于以上知识编写Linux shell作为练 ...
- Django 基本设置
建立django目录,为了独立区分app和主站的关系,需要把app完全和主站分离 app/views.py from django.shortcuts import render from djang ...
- VisualVM 使用 service:jmx:rmi:///...无法连接linux远程服务器
VisualVM 无法使用 service:jmx:rmi:///jndi/rmi:///jmxrmi 连接到 关闭远程机器的防火墙即可:service iptables stop 不关闭防火墙的解决 ...