[USACO11DEC]牧草种植Grass Planting

图很丑。明显的树链剖分,需要的操作只有区间修改和区间查询。不过这里是边权,我们怎么把它转成点权呢?对于E(u,v),我们选其深度大的节点,把边权扔给它。因为这是树,所以每个点只有一个父亲,所以每个边权都可以唯一地、不重复地转移到点上去(除了根节点)。但是做区间操作时就要注意一下,区间两边端点的LCA的权值是不可以用的。
这么简单的模板题就直接放代码了:
#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 1000001
#define maxm 1000001
using namespace std; struct edge{
int to,next;
edge(){}
edge(const int &_to,const int &_next){ to=_to,next=_next; }
}e[maxn<<];
int head[maxn],k; struct node{
int l,r,c,f;
}t[maxn<<]; int size[maxn],son[maxn],fa[maxn],dep[maxn];
int dfn[maxn],id[maxn],top[maxn],tot;
int n,m; inline int read(){
register int x(); register char c(getchar());
while(c<''||''<c) c=getchar();
while(''<=c&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x;
} inline void add(const int &u,const int &v){
e[k]=edge(v,head[u]);
head[u]=k++;
} void dfs_getson(int u){
size[u]=;
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v==fa[u]) continue;
fa[v]=u,dep[v]=dep[u]+;
dfs_getson(v);
size[u]+=size[v];
if(size[v]>size[son[u]]) son[u]=v;
}
} void dfs_rewrite(int u,int tp){
top[u]=tp,dfn[u]=++tot,id[tot]=u;
if(son[u]) dfs_rewrite(son[u],tp);
for(register int i=head[u];~i;i=e[i].next){
int v=e[i].to;
if(v!=son[u]&&v!=fa[u]) dfs_rewrite(v,v);
}
} void build(int d,int l,int r){
t[d].l=l,t[d].r=r;
if(l==r) return;
int mid=(l+r)>>;
build(d<<,l,mid),build(d<<|,mid+,r);
} inline void down(const int &d){
t[d<<].c+=t[d].f*(t[d<<].r-t[d<<].l+),t[d<<].f+=t[d].f;
t[d<<|].c+=t[d].f*(t[d<<|].r-t[d<<|].l+),t[d<<|].f+=t[d].f;
t[d].f=;
} void change(int d,const int &l,const int &r){
if(l<=t[d].l&&t[d].r<=r){
t[d].c+=t[d].r-t[d].l+,t[d].f++;
return;
}
if(t[d].f) down(d);
int mid=(t[d].l+t[d].r)>>;
if(l<=mid) change(d<<,l,r);
if(r>mid) change(d<<|,l,r);
t[d].c=t[d<<].c+t[d<<|].c;
} inline void change_path(){
int u=read(),v=read();
while(top[u]!=top[v]){
if(dep[top[u]]>dep[top[v]]) swap(u,v);
change(,dfn[top[v]],dfn[v]);
v=fa[top[v]];
}
if(dep[u]>dep[v]) swap(u,v);
change(,dfn[u]+,dfn[v]);//加1是因为不能用LCA的权值
} int getsum(int d,const int &l,const int &r){
if(l<=t[d].l&&t[d].r<=r) return t[d].c;
if(t[d].f) down(d);
int mid=(t[d].l+t[d].r)>>,ans=;
if(l<=mid) ans+=getsum(d<<,l,r);
if(r>mid) ans+=getsum(d<<|,l,r);
return ans;
} inline void getsum_path(){
int u=read(),v=read(),ans=;
while(top[u]!=top[v]){
if(dep[top[u]]>dep[top[v]]) swap(u,v);
ans+=getsum(,dfn[top[v]],dfn[v]);
v=fa[top[v]];
}
if(dep[u]>dep[v]) swap(u,v);
ans+=getsum(,dfn[u]+,dfn[v]);//加1是因为不能用LCA的权值
printf("%d\n",ans);
} int main(){
memset(head,-,sizeof head);
n=read(),m=read();
int u,v;
for(register int i=;i<n;i++){
u=read(),v=read();
add(u,v),add(v,u);
}
dfs_getson();
dfs_rewrite(,);
build(,,tot); char op;
for(register int i=;i<=m;i++){
scanf("%s",&op);
if(op=='P') change_path();
else getsum_path();
}
return ;
}
[USACO11DEC]牧草种植Grass Planting的更多相关文章
- 洛谷P3038 [USACO11DEC]牧草种植Grass Planting
题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...
- 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
题目描述 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(树链剖分)
题解:仍然是无脑树剖,要注意一下边权,然而这种没有初始边权的题目其实和点权也没什么区别了 代码如下: #include<cstdio> #include<vector> #in ...
- 【LuoguP3038/[USACO11DEC]牧草种植Grass Planting】树链剖分+树状数组【树状数组的区间修改与区间查询】
模拟题,可以用树链剖分+线段树维护. 但是学了一个厉害的..树状数组的区间修改与区间查询.. 分割线里面的是转载的: ----------------------------------------- ...
- 树链剖分【p3038】[USACO11DEC]牧草种植Grass Planting
表示看不太清. 概括题意 树上维护区间修改与区间和查询. 很明显树剖裸题,切掉,细节处错误T了好久 TAT 代码 #include<cstdio> #include<cstdlib& ...
- 洛谷P3038 牧草种植Grass Planting
思路: 首先,这道题的翻译是有问题的(起码现在是),查询的时候应该是查询某一条路径的权值,而不是某条边(坑死我了). 与平常树链剖分题目不同的是,这道题目维护的是边权,而不是点权,那怎么办呢?好像有点 ...
- USACO Grass Planting
洛谷 P3038 [USACO11DEC]牧草种植Grass Planting 洛谷传送门 JDOJ 2282: USACO 2011 Dec Gold 3.Grass Planting JDOJ传送 ...
随机推荐
- asp+SqlServer2008开发【第三集:win2winSSH远程连接—像连接Linux一样操作】
1,参考:https://blog.csdn.net/flyingshuai/article/details/72897692 和https://blog.csdn.net/nijiayy/artic ...
- 大数据项目之_15_电信客服分析平台_01&02_项目背景+项目架构+项目实现+数据生产+数据采集/消费(存储)
一.项目背景二.项目架构三.项目实现3.1.数据生产3.1.1.数据结构3.1.2.编写代码3.1.3.打包测试3.2.数据采集/消费(存储)3.2.1.数据采集:采集实时产生的数据到 kafka 集 ...
- WebSocket的Tomcat实现
一.WebSocket简单介绍 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通 ...
- opencv coudn't find video stream from "XXX(文件名)"
opencv coudn't find video stream from "XXX(文件名)" 我用的是clion 解决方法: 把路径设为完整路径,如"C:/XXX&q ...
- 如何使用RestTemplate访问restful服务
一. 什么是RestTemplate 传统情况下在java代码里访问restful服务,一般使用Apache的HttpClient.不过此种方法使用起来太过繁琐.spring提供了一种简单便捷的模板类 ...
- 转UI么?不想
最近一直在弄UI 对于UI实在是不想弄了 很痛苦...我一开始都比较热衷后台开发 但是前端UI 我只是有点兴趣而已,但是还一直要做...太累了 或许要学的东西还是有很多的!一直不知道 ...
- ECMA Script 6_模块加载方案 ES6 Module 模块语法_import_export
1. 模块加载方案 commonJS 背景: 历史上,JavaScript 一直没有模块(module)体系, 无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来. 其他语言都有这项功能: ...
- Web版记账本开发记录(一)代码和功能展示
一丶基本机构 数据库截图 record表 年份表 index.jsp <%@ page language="java" contentType="text/html ...
- JavaScript 中的FileReader对象(实现上传图片预览)
方法一:使用js的FileReader对象 1.FileReader对象简介 1.检测浏览器对FileReader的支持 if(window.FileReader) { var fr = new Fi ...
- MYSQL 导入导出数据库文件
一.从数据库导出数据库或表文件: mysqldump -u用戶名 -p密码 -d 数据库名 表名 > 脚本名; 导出整个数据库结构和数据mysqldump -h localhost -uroot ...