[USACO11DEC] Grass Planting (树链剖分)
题目描述
Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional roads, such that there is exactly one path between any two pastures. Bessie, a cow who loves her grazing time, often complains about how there is no grass on the roads between pastures. Farmer John loves Bessie very much, and today he is finally going to plant grass on the roads. He will do so using a procedure consisting of M steps (1 <= M <= 100,000).
At each step one of two things will happen:
FJ will choose two pastures, and plant a patch of grass along each road in between the two pastures, or,
Bessie will ask about how many patches of grass on a particular road, and Farmer John must answer her question.
Farmer John is a very poor counter -- help him answer Bessie's questions!
给出一棵n个节点的树,有m个操作,操作为将一条路径上的边权加一或询问某条边的权值。
输入输出格式
输入格式:
Line 1: Two space-separated integers N and M
Lines 2..N: Two space-separated integers describing the endpoints of a road.
Lines N+1..N+M: Line i+1 describes step i. The first character of the line is either P or Q, which describes whether or not FJ is planting grass or simply querying. This is followed by two space-separated integers A_i and B_i (1 <= A_i, B_i <= N) which describe FJ's action or query.
输出格式:
- Lines 1..???: Each line has the answer to a query, appearing in the same order as the queries appear in the input.
输入输出样例
输入样例#1:
4 6
1 4
2 4
3 4
P 2 3
P 1 3
Q 3 4
P 1 4
Q 2 4
Q 1 4
输出样例#1:
2
1
2
Solution
树剖板子题,关键是注意统计的是边的权值,不是点的权值。
只需要在每次修改或者查询的时候将其 LCA 的 id +1,即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=100008;
int n,m;
struct sj{
int to;
int next;
}a[maxn*2];
int size,head[maxn];
void add(int x,int y)
{
a[++size].to=y;
a[size].next=head[x];
head[x]=size;
}
int dep[maxn],fa[maxn];
int top[maxn],son[maxn];
int siz[maxn];
void dfs(int x)
{
siz[x]=1;
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
if(!siz[tt])
{
dep[tt]=dep[x]+1;
fa[tt]=x;
dfs(tt);
siz[x]+=siz[tt];
if(siz[tt]>siz[son[x]])
son[x]=tt;
}
}
}
int id[maxn],num;
void dfs1(int x,int y)
{
top[x]=y;
id[x]=++num;
if(son[x])
dfs1(son[x],y);
for(int i=head[x];i;i=a[i].next)
{
int tt=a[i].to;
if(!top[tt])
if(tt!=son[x])
dfs1(tt,tt);
}
}
int sgm[maxn*4],lazy[maxn*4];
void push_down(int node,int l,int r)
{
int kk=lazy[node],mid=(l+r)/2;
lazy[node*2]+=kk;
lazy[node*2+1]+=kk;
sgm[node*2]+=(mid-l+1)*kk;
sgm[node*2+1]+=(r-mid)*kk;
lazy[node]=0;
}
void change(int node,int left,int right,int l,int r)
{
int v=1;
if(left>r||right<l)
return;
if(left>=l&&right<=r)
{
sgm[node]+=v*(right-left+1);
lazy[node]+=v;
return;
}
push_down(node,left,right);
int dist=(right+left)/2;
change(node*2,left,dist,l,r);
change(node*2+1,dist+1,right,l,r);
sgm[node]=sgm[node*2]+sgm[node*2+1];
return;
}
int query(int node,int left,int right,int l,int r)
{
if(l>right||r<left)
return 0;
if(right<=r&&left>=l)
return sgm[node];
push_down(node,left,right);
int dist=(left+right)/2;
return query(node*2,left,dist,l,r)+query(node*2+1,dist+1,right,l,r);
}
void kuai(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
change(1,1,n,id[top[x]],id[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
change(1,1,n,id[x]+1,id[y]);
return;
}
int check(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans+=query(1,1,n,id[top[x]],id[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
ans+=query(1,1,n,id[x]+1,id[y]);
return ans;
}
int main()
{
cin>>n>>m;
for(int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
dep[1]=1;
dfs(1);
dfs1(1,1);
while(m--)
{
char ch;
int x,y;
cin>>ch; scanf("%d%d",&x,&y);
if(ch=='Q')
cout<<check(x,y)<<endl;
else
kuai(x,y);
}
}
[USACO11DEC] Grass Planting (树链剖分)的更多相关文章
- 洛谷 P3038 [USACO11DEC]牧草种植Grass Planting(树链剖分)
题解:仍然是无脑树剖,要注意一下边权,然而这种没有初始边权的题目其实和点权也没什么区别了 代码如下: #include<cstdio> #include<vector> #in ...
- 【LuoguP3038/[USACO11DEC]牧草种植Grass Planting】树链剖分+树状数组【树状数组的区间修改与区间查询】
模拟题,可以用树链剖分+线段树维护. 但是学了一个厉害的..树状数组的区间修改与区间查询.. 分割线里面的是转载的: ----------------------------------------- ...
- spoj - Grass Planting(树链剖分模板题)
Grass Planting 题意 给出一棵树,树有边权.每次给出节点 (u, v) ,有两种操作:1. 把 u 到 v 路径上所有边的权值加 1.2. 查询 u 到 v 的权值之和. 分析 如果这些 ...
- 树链剖分好(du)题(liu)选做
1.luogu P4315 月下"毛景树" 题目链接 前言: 这大概是本蒟蒻A掉的题里面码量最大的一道题了.我自认为码风比较紧凑,但还是写了175行. 从下午2点多调到晚上8点.中 ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)
题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...
- 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)
题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...
随机推荐
- 斐讯k2p 月光银 硬件版本A2-软件版本22.7.8.5 刷官改系统
Mark https://huabuyu.net/斐讯k2p%20月光银%20硬件版本A2-软件版本22.7.8.5%20刷官改系统.html 详细资源推荐:恩山论坛 https://www.righ ...
- 用python写trojan的过程中遇到的各种问题
由于之前已经conn, addr = s.accept() 所以改为 conn.recv spyder无法同时运行client 和 server 分别在spyder和anaconda prompt运 ...
- CMDB数据库设计
title: CMDB 数据库设计 tags: Django --- CMDB数据库设计 具体的资产 服务器表和网卡.内存.硬盘是一对多的关系,一个服务器可以有多个网卡.多个内存.多个硬盘 hostn ...
- Mysql查询指定用户并列排名 类似rank函数
SELECT total.* FROM ( SELECT obj.uid, obj.score, CASE WHEN @rowtotal = obj.score THEN @rownum WHEN @ ...
- python 产生随机数
Python中的random模块用于生成随机数.下面介绍一下random模块中最常用的几个函数. random.random random.random()用于生成一个0到1的随机符点数: 0 < ...
- (转发)IOS动画中的枚举UIViewAnimationOptions
若本帖转自(博客园·小八究):http://www.cnblogs.com/xiaobajiu/p/4084747.html 可怜目前天朝搜不到什么有价值的东西方便学习,在这里方便初学者. 首先这个枚 ...
- errno的用法
Linux中系统调用的错误都存储于 errno中,errno由操作系统维护,存储就近发生的错误,即下一次的错误码会覆盖掉上一次的错误. 编程时需要包含#include <errno.h>, ...
- 【上下界网络流 二分】bzoj2406: 矩阵
感觉考试碰到上下界网络流也还是写不来啊 Description Input 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. Output 第一行,输出 ...
- 【状压dp】cf906C. Party
需要稍加分析结论:还有一些小细节 Arseny likes to organize parties and invite people to it. However, not only friends ...
- w3resource_MySQL练习:Subquery
w3resource_MySQL练习题:Subquery 1. Write a query to find the name (first_name, last_name) and the salar ...