大致题意: 维护一棵树,支持两种操作:

P x y x到y路径上的每条边的值+1;
Q x y 询问x到y路径上所有边的值的和。
Input
第一行两个正整数,N,M表示点数和操作数;
接下来N-1行每行两个数表示一条边;
接下来M行表示M个操作,每行形如P x y或Q x y。
2≤N≤100,000,1≤M≤100,000。
Output
M行,对应相应询问的答案。
Sample Input
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
Sample Output
2
1
2

/*
大致题意: 维护一棵树,支持两种操作:
P x y x到y路径上的每条边的值+1;
Q x y 询问x到y路径上所有边的值的和
*/
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=100050;
int m;
int read()
{
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
struct segment_tree
{
int sum[maxn*8],lazy[maxn*8];
void updata(int p){sum[p]=sum[p<<1]+sum[p<<1|1];}
void add_tag(int p,int v)
{
lazy[p]+=v;
sum[p]+=v;
}
void pushdown(int p)
{
if(!lazy[p])return;
add_tag(p<<1,lazy[p]);
add_tag(p<<1|1,lazy[p]);
lazy[p]=0;
}
void add(int p,int l,int r,int x,int y)
{
if(x>y)return;
if(x<=l&&r<=y)
{
add_tag(p,1);
return;
}
int mid=(l+r)>>1;
pushdown(p);
if(x<=mid)
add(p<<1,l,mid,x,y);
if(y>mid)
add(p<<1|1,mid+1,r,x,y);
updata(p);
}
int query(int p,int l,int r,int x,int y)
{
if(x>y)return 0;
if(x<=l&&r<=y)
return sum[p];
int mid=(l+r)>>1,ls=0,rs=0;
pushdown(p);
if(x<=mid)
ls=query(p<<1,l,mid,x,y);
if(y>mid)
rs=query(p<<1|1,mid+1,r,x,y);
return ls+rs;
}
}ST;
struct Tree
{
int n,tot,cnt;
int pre[maxn*2],son[maxn*2],now[maxn];
int dep[maxn],fa[maxn],siz[maxn],wson[maxn],top[maxn],seg[maxn];
void add(int a,int b)
{
pre[++tot]=now[a];
now[a]=tot;
son[tot]=b;
}
void in()
{
n=read(),m=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
add(x,y);
add(y,x);
}
}
void dfs(int faa,int u)
{
fa[u]=faa;
dep[u]=dep[faa]+1;
siz[u]=1;
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(v!=faa)
{
dfs(u,v);
siz[u]+=siz[v];
if(siz[wson[u]]<siz[v])wson[u]=v;
}
}
void base(int tp,int u) //树链剖分
{
top[u]=tp;
seg[u]=++cnt;
if(wson[u])
base(tp,wson[u]);
for(int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if(v!=fa[u]&&v!=wson[u])base(v,v);
}
void addedg(int a,int b) //a到b的路径上边都加1
{
while(top[a]!=top[b])
{
if(dep[top[a]]<dep[top[b]])
swap(a,b);
ST.add(1,1,n,seg[top[a]],seg[a]);
a=fa[top[a]];
}
if(dep[a]<dep[b])
swap(a,b);
ST.add(1,1,n,seg[b]+1,seg[a]);
//注意是对边操作,所以是seg[b]+1
}
void query(int a,int b)
{
int ans=0;
while(top[a]!=top[b])
{
if(dep[top[a]]<dep[top[b]])swap(a,b);
ans+=ST.query(1,1,n,seg[top[a]],seg[a]);
a=fa[top[a]];
}
if(dep[a]<dep[b])
swap(a,b);
ans+=ST.query(1,1,n,seg[b]+1,seg[a]);
printf("%d\n",ans);
}
}CT;
void work()
{
for(int i=1;i<=m;i++)
{
char s[10];int x,y;
scanf("%s",s);
x=read(),y=read();
if(s[0]=='P') //路径上加1
CT.addedg(x,y);
else
CT.query(x,y);
}
}
int main()
{
CT.in();
CT.dfs(0,1);
CT.base(1,1);
work();
return 0;
}

  

Grass Planting的更多相关文章

  1. spoj - Grass Planting(树链剖分模板题)

    Grass Planting 题意 给出一棵树,树有边权.每次给出节点 (u, v) ,有两种操作:1. 把 u 到 v 路径上所有边的权值加 1.2. 查询 u 到 v 的权值之和. 分析 如果这些 ...

  2. USACO Grass Planting

    洛谷 P3038 [USACO11DEC]牧草种植Grass Planting 洛谷传送门 JDOJ 2282: USACO 2011 Dec Gold 3.Grass Planting JDOJ传送 ...

  3. 洛谷P3038 [USACO11DEC]牧草种植Grass Planting

    题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...

  4. [USACO11DEC] Grass Planting (树链剖分)

    题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...

  5. AC日记——[USACO11DEC]牧草种植Grass Planting 洛谷 P3038

    题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...

  6. [Usaco2011 Dec]Grass Planting

    Description Farmer John has N barren pastures connected by N-1 bidirectional roads, such that there ...

  7. 洛谷 P3038 [USACO11DEC]牧草种植Grass Planting

    题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...

  8. P3038 [USACO11DEC]牧草种植Grass Planting

    题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirectional road ...

  9. 【 SPOJ - GRASSPLA】 Grass Planting (树链剖分+树状数组)

    54  种草约翰有 N 个牧场,编号为 1 到 N.它们之间有 N − 1 条道路,每条道路连接两个牧场.通过这些道路,所有牧场都是连通的.刚开始的时候,所有道路都是光秃秃的,没有青草.约翰会在一些道 ...

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

    题解:仍然是无脑树剖,要注意一下边权,然而这种没有初始边权的题目其实和点权也没什么区别了 代码如下: #include<cstdio> #include<vector> #in ...

随机推荐

  1. 洛谷P3374 【模板】树状数组 1&&P3368 【模板】树状数组 2题解

    图片来自度娘~~ 树状数组形如上图,是一种快速查找区间和,快速修改的一种数据结构,一个查询和修改复杂度都为log(n),树状数组1和树状数组2都是板子题,在这里进行详解: 求和: 首先我们看一看这个图 ...

  2. FPDF_CHAR_INFO

    typedef struct { FX_WCHAR m_Unicode; FX_WCHAR m_Charcode; FX_INT32 m_Flag; FX_FLOAT m_FontSize; FX_F ...

  3. 如何使用Beyond Compare比较两个文件夹的差异

    很多时候,我们需要比较两个文件或者两个文件夹的差异性,看看是哪里不同.这时候就需要一款比较软件来处理,Beyond Compare就是其中一款非常好用的版本比较工具,下面简单介绍一下Beyond Co ...

  4. Linux中profile(转载)

    原文地址:http://www.cnblogs.com/mmfzmd517528/archive/2012/07/05/2577988.html 标黄是个人批注. 环境变量就是一个系统变量,系统配置一 ...

  5. Quartz(二)

    1 SchedulerFactory 1.1 概述 Quartz是以模块的方式构建的,因为,要使它运行,几个组件必须很好的组合在一起.非常幸运的是,已经有了一些现存的助手可以完成这些工作. 所有Sch ...

  6. 使用vue开发输入型组件更好的一种解决方式(子组件向父组件传值,基于2.2.0)

    (本人想封装一个带有input输入框的组件) 之前使用vue开发组件的时候,在遇到子组件向父组件传递值时我采用的方法是这样的: 比如子组件是一个输入框,父组件调用时需要获取到子组件输入的值,子组件通过 ...

  7. 汇总apply()、call()、bind()用法详解

    先看明白下面: 例 1 obj.objAge; // 17 obj.myFun() // 小张年龄 undefined 例 2 shows() // 盲僧 比较一下这两者 this 的差别,第一个打印 ...

  8. BZOJ 5028 小z的加油站

    bzoj链接 Time limit 10000 ms Memory limit 262144 kB OS Linux 感想 树上动态gcd的第二题也好了. [x] BZOJ 2257 [JSOI200 ...

  9. css使用1

    一.引入css的三种方式 一.CSS(Cascading Style Sheet):层叠样式表 二.CSS样式由两个组成部分:选择器和声明.声明又包括属性和属性值.每个声明之后用分号结束 语法结构 选 ...

  10. 在线前端 JS 或 HTML 或 CSS 编写 Demo 处 JSbin 与 jsFiddle 比较

    JSBin 该编辑器的特点是编写可直接编写 HTML.CSS.JavaScript 并且可以在 output 中实时观察编写效果:可设置自动运行 JavasScript 代码,其中最大的好处是有一个 ...