[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传送 ...
随机推荐
- python全栈开发day102-django rest-framework框架
1.频次访问组件 1) 手写版本 # class VisitThrottle(BaseThrottle): # # def __init__(self): # self.history = None ...
- Centos6的yum源
更换原因: yum -y install fping 1.阿里云Linux安装软件镜像源 常用的源: 阿里云是最近新出的一个镜像源.得益与阿里云的高速发展,这么大的需求,肯定会推出自己的镜像源.阿里云 ...
- python进阶篇
python进阶篇 import 导入模块 sys.path:获取指定模块搜索路径的字符串集合,可以将写好的模块放在得到的某个路径下,就可以在程序中import时正确找到. import sys ...
- react-native flatlist 上拉加载onEndReached方法频繁触发的问题
问题 在写flatlist复用组件时,调用的时候如果父组件是不定高的组件,会造成组件无法显示 如果父组件样式{flex:1},则会出现下拉方法频繁触发或不正常触发的问题(我这里出现的问题是在列表第6个 ...
- win10安装ubuntu16.04双系统历程
目录 win10安装ubuntu16.04双系统 历程 安装时间 安装准备 安装过程 其他问题 win10安装ubuntu16.04双系统 历程 安装时间 2018.11.30 安装准备 u盘(格式化 ...
- __x__(48)0910第六天__CSS Hack
CSS Hack: 不到万不得已,不要使用.不易于维护. 有一些情况,需要一段特殊代码在遇到特殊浏览器环境才执行,而在其他条件下,不执行. 此时,CSS Hack 就能实现. CSS Hack 实际上 ...
- js根据服务端返回的时间倒计时
使用服务端与本地的时间差进行计算 $(function(){ // 倒计时 var _ordertimer = null; var data =new Date(); var txt = $('.js ...
- Linux_相关命令(学习,备忘)
1.Linux 查看实时cpu使用率: top 说明:top命令即时显示process的动态 2.查看cpu处理器使用率: cat /proc/stat 3.平均cpu使用率 4.赋予文件夹下所有文件 ...
- 19.3.19 使用Flask框架搭建一个简易登录服务器
import Flask import json from Flask import request server1 = flask.Flask(__name__) #实例化一个flask对象 @se ...
- 课堂动手动脑String
一 public class StringPool { public static void main(String args[]) { String s0="Hello"; St ...