题目描述

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

树剖裸题

链上修改+查询

屠龙宝刀点击就送

#include <ctype.h>
#include <cstdio>
#define M 100005
void read(int &x)
{
x=;register char ch=getchar();
for(;!isdigit(ch);ch=getchar());
for(;isdigit(ch);ch=getchar()) x=x*+ch-'';
}
struct Edge
{
int next,to;
Edge (int next=,int to=):next(next),to(to) {}
}edge[M<<];
int n,m,head[M],cnt,top[M],belong[M],tim,size[M],dad[M],dep[M];
void insert(int u,int v)
{
edge[++cnt]=Edge(head[u],v);
head[u]=cnt;
}
void swap(int &x,int &y)
{
int tmp=y;
y=x;
x=tmp;
}
struct node
{
int mid,l,r,dis,flag;
node *left,*right;
node ()
{
left=right=NULL;
dis=flag=;
}
}*root;
class t
{
public:
void pushup(node *&k)
{
k->dis=k->left->dis+k->right->dis;
}
void pushdown(node *&k)
{
if(k->l==k->r) return;
k->left->flag+=k->flag;
k->right->flag+=k->flag;
k->left->dis+=k->flag*(k->left->r-k->left->l+);
k->right->dis+=k->flag*(k->right->r-k->right->l+);
k->flag=;
}
void build(node *&k,int l,int r)
{
k=new node;
k->l=l;k->r=r;k->mid=(l+r)>>;
if(l==r) return;
build(k->left,l,k->mid);
build(k->right,k->mid+,r);
}
void Tree_change(node *&k,int l,int r)
{
if(k->l==l&&k->r==r)
{
k->flag++;
k->dis+=(r-l+);
return;
}
if(l>k->mid) Tree_change(k->right,l,r);
else if(r<=k->mid) Tree_change(k->left,l,r);
else Tree_change(k->left,l,k->mid),Tree_change(k->right,k->mid+,r);
pushup(k);
}
int Tree_query(node *&k,int l,int r)
{
if(k->l==l&&k->r==r) return k->dis;
if(k->flag) pushdown(k);
if(l>k->mid) return Tree_query(k->right,l,r);
else if(r<=k->mid) return Tree_query(k->left,l,r);
else return Tree_query(k->left,l,k->mid)+Tree_query(k->right,k->mid+,r);
pushup(k);
}
};
class t Tree;
class sp
{
public :
void dfs1(int x)
{
size[x]=;
dep[x]=dep[dad[x]]+;
for(int i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if(dad[x]!=v)
{
dad[v]=x;
dfs1(v);
size[x]+=size[v];
}
}
}
void dfs2(int x)
{
int pos=;
belong[x]=++tim;
if(!top[x]) top[x]=x;
for(int i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if(dad[x]!=v&&size[pos]<size[v]) pos=v;
}
if(pos) top[pos]=top[x],dfs2(pos);
for(int i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
if(dad[x]!=v&&v!=pos) dfs2(v);
}
}
void Chain_change(int x,int y)
{
for(;top[x]!=top[y];x=dad[top[x]])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
Tree.Tree_change(root,belong[top[x]],belong[x]);
}
if(x==y) return;
if(dep[x]>dep[y]) swap(x,y);
Tree.Tree_change(root,belong[x]+,belong[y]);
}
int Chain_query(int x,int y)
{
int ans=;
for(;top[x]!=top[y];x=dad[top[x]])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=Tree.Tree_query(root,belong[top[x]],belong[x]);
}
if(x==y) return ans;
if(dep[x]>dep[y]) swap(x,y);
ans+=Tree.Tree_query(root,belong[x]+,belong[y]);
return ans;
}
};
class sp Chain;
int main()
{
read(n);
read(m);
for(int x,y,i=;i<n;i++)
{
read(x);
read(y);
insert(x,y);
insert(y,x);
}
Chain.dfs1();Chain.dfs2();
char str[];
root=new node;
Tree.build(root,,n);
for(int x,y;m--;)
{
scanf("%s",str+);
read(x);
read(y);
if(str[]=='P') Chain.Chain_change(x,y);
else printf("%d\n",Chain.Chain_query(x,y));
}
return ;
}

洛谷 P3038 [USACO11DEC]牧草种植Grass Planting的更多相关文章

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

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

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

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

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

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

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

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

  5. 树链剖分【p3038】[USACO11DEC]牧草种植Grass Planting

    表示看不太清. 概括题意 树上维护区间修改与区间和查询. 很明显树剖裸题,切掉,细节处错误T了好久 TAT 代码 #include<cstdio> #include<cstdlib& ...

  6. [USACO11DEC]牧草种植Grass Planting

    图很丑.明显的树链剖分,需要的操作只有区间修改和区间查询.不过这里是边权,我们怎么把它转成点权呢?对于E(u,v),我们选其深度大的节点,把边权扔给它.因为这是树,所以每个点只有一个父亲,所以每个边权 ...

  7. 【LuoguP3038/[USACO11DEC]牧草种植Grass Planting】树链剖分+树状数组【树状数组的区间修改与区间查询】

    模拟题,可以用树链剖分+线段树维护. 但是学了一个厉害的..树状数组的区间修改与区间查询.. 分割线里面的是转载的: ----------------------------------------- ...

  8. 洛谷P3038 牧草种植Grass Planting

    思路: 首先,这道题的翻译是有问题的(起码现在是),查询的时候应该是查询某一条路径的权值,而不是某条边(坑死我了). 与平常树链剖分题目不同的是,这道题目维护的是边权,而不是点权,那怎么办呢?好像有点 ...

  9. 洛谷P3038 牧草种植 [树链剖分]

    题目传送门 牧草种植 题目描述 Farmer John has N barren pastures (2 <= N <= 100,000) connected by N-1 bidirec ...

随机推荐

  1. 书写优雅的shell脚本(插曲) - kill

    shell之kill.killall.xkill.pkill 2013-01-08 22:03:28|  分类: Linux|举报|字号订阅 1 kill kill的应用是和ps 或pgrep 命令结 ...

  2. (转)Vim自动补全神器:YouCompleteMe

    原文出处:http://blog.jobbole.com/58978/ 第一次听说这个插件还是在偶然的情况下看到别人的博客,听说了这个插件的大名.本来打算在实训期间来完成安装的,无奈网实在不给力,也就 ...

  3. MFC之document与view实践总结

    Document/View是MFC的基石,负责程序数据的管理和显示,Doculent和Viewd的关系有一档一视,一档多视和多档多视,下面将分别对实现过程中的重点知识进行总结. 1. 视图的同步更新 ...

  4. 【USACO2017JAN】 Promotion Counting

    [题目链接] 点击打开链接 [算法] 离散化 + dfs + 树状数组 [代码] #include<bits/stdc++.h> using namespace std; #define ...

  5. Python项目使用memcached缓存

    前言许多Web应用都将数据保存到MySQL这样的关系型数据库管理系统中,应用服务器从中读取数据并在浏览器中显示. 但随着数据量的增大.访问的集中,就会出现数据库的负担加重.数据库响应恶化. 网站显示延 ...

  6. [angularJS]ng-hide|ng-show切换

    <div class="row ng-scope"> <div class="col-lg-12"> <h1 class=&quo ...

  7. 安装ubuntu gnome 16.04后的一些操作

    好吧...其实安装了挺久了,记录一下以防忘记... 1.软件 chrome浏览器 唔..自己去官网下吧.. gnome tweak tool 不用多说,必备 sudo apt-get install  ...

  8. 获取服务器基本信息.sh

    #获取linux服务器基本信息脚本 #!/bin/bash # #Name:system_info #Ver:1.0 #Author:lykyl # # #程序说明: #获取服务器基本信息脚本 # e ...

  9. UVaLive 7455 Linear Ecosystem (Gaussi 消元)

    题意:对一个k元向量, 每次左乘一个k*k的矩阵得到新的向量.问经过一定次数的左乘后,能否使得该向量不再变化. (同时要求此时向量非零). 析:设初始向量为A,矩阵为P.由于每次矩阵P都是左乘A, 那 ...

  10. ASP.NET Core MVC 打造一个简单的图书馆管理系统 (修正版)(七) 学生信息增删

    前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/asp ...