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

时间:2021-08-11 00:55:45

54  种草
约翰有 N 个牧场,编号为 1 到 N。它们之间有 N 1 条道路,每条道路连接两个牧场。通过这
些道路,所有牧场都是连通的。
刚开始的时候,所有道路都是光秃秃的,没有青草。约翰会在一些道路上批量种草。每次开始种
草的时候,约翰会选择一个牧场作为起点,一个牧场作为终点,找到从起点到终点的最短路径,在这
条路径上所有的道路上分别种下一棵新的青草。
贝西在监督约翰的工作,她迫不及待地想知道每条道路上已经有多少青草了。约翰的工作总是被
贝西打断,他不胜其烦,所以请你来帮忙回答贝西的问题。约翰的工作和贝西的询问是穿插进行的,
输入数据将会依次出现 M 个事件,以字符 P 开头的事件表示约翰在一条路径上种植了青草,以字符
Q 开头的事件表示贝西在查询一条道路上有多少青草。
输入格式
• 第一行:两个整数 N M, 2 N 105 , 1 M 105
• 第二行到第 N 行:第 i + 1 行有两个整数 Ui Vi,表示第 i 条道路连接的两个牧场编号,
1 Ui,Vi N
• 第 N + 1 行到第 N + Q 行:每行首先由一个大写字母:
如果是 P,随后会有两个整数 A B,表示约翰在从 A 通向 B 的每条道路上都新种了一
棵青草, 1 A,B N
如果是 Q,随后会有两个整数 A B,表示贝西查询一条道路上的青草数量, A B
这条道路的两个端点, 1 A,B N,保证输入数据中存在一条 A B 的道路
输出格式
• 对每个查询请求,输出该条道路上青草的数量,以换行符分隔
样例输入
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
样例输出
212

【分析】

  因为是树状数组专题,于是我打了树状数组没有打线段树。

  表示人生第一次树状数组的区间修改和区间查询(我太垃圾..

  其实比线段树可还是短多了,就是维护两个东西的前缀和,一个是delta[i],一个是delta[i]*i,delta[i]表示i~n的共同增量。

  具体看我转的那篇东西:http://www.cnblogs.com/Konjakmoyu/p/5981935.html

  然后就是树剖啦ORZ,好多年没打了居然还能打出来ORZ...

代码如下:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define Maxn 100010 struct node
{
int x,y,next;
}t[Maxn*];int len;
int first[Maxn]; void ins(int x,int y)
{
t[++len].x=x;t[len].y=y;
t[len].next=first[x];first[x]=len;
} char s[]; int sm[Maxn],son[Maxn],fa[Maxn],dep[Maxn];
void dfs(int x,int f)
{
sm[x]=;son[x]=;fa[x]=f;dep[x]=dep[f]+;
for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
{
int y=t[i].y;
dfs(y,x);
sm[x]+=sm[y];
if(sm[y]>sm[son[x]]) son[x]=y;
}
} int tp[Maxn],dfn[Maxn],cnt;
void dfs2(int x,int tpp)
{
if(x==) return;
dfn[x]=++cnt;tp[x]=tpp;
dfs2(son[x],tpp);
for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x])
{
int y=t[i].y;
if(y==son[x]) continue;
dfs2(y,y);
}
} int c1[Maxn],c2[Maxn]; void ffind(int x,int y,int c)
{
for(int i=x;i<=cnt;i+=i&(-i))
c1[i]+=c,c2[i]+=c*x;
y++;
for(int i=y;i<=cnt;i+=i&(-i))
c1[i]+=-c,c2[i]+=(-c)*y;
} int get_ans(int x,int y)
{
int ans=;
for(int i=y;i>=;i-=i&(-i))
ans+=(y+)*c1[i]-c2[i];
x--;
for(int i=x;i>=;i-=i&(-i))
ans-=(x+)*c1[i]-c2[i];
return ans;
} void change(int x,int y)
{
int tt;
while(tp[x]!=tp[y])
{
if(dep[tp[x]]>dep[tp[y]])
{
tt=x,x=y,y=tt;
}
ffind(dfn[tp[y]],dfn[y],);
y=fa[tp[y]];
}
if(x==y) return;
if(dep[x]>dep[y]) tt=x,x=y,y=tt;
ffind(dfn[x]+,dfn[y],);
} int query(int x,int y)
{
int ans=;
int tt;
while(tp[x]!=tp[y])
{
if(dep[tp[x]]>dep[tp[y]])
{
tt=x,x=y,y=tt;
}
ans+=get_ans(dfn[tp[y]],dfn[y]);
y=fa[tp[y]];
}
if(x==y) return ans;
if(dep[x]>dep[y]) tt=x,x=y,y=tt;
ans+=get_ans(dfn[x]+,dfn[y]);
return ans;
} int main()
{
int n,m;
scanf("%d%d",&n,&m);
len=;
memset(first,,sizeof(first));
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ins(x,y);ins(y,x);
}
sm[]=;dep[]=;
dfs(,);
cnt=;
dfs2(,); memset(c1,,sizeof(c1));
memset(c2,,sizeof(c2));
for(int i=;i<=m;i++)
{
int x,y;
scanf("%s%d%d",s,&x,&y);
if(s[]=='P')
{
change(x,y);
}
else
{
printf("%d\n",query(x,y));
}
}
return ;
}

【SPOJ GRASSPLA】

2016-10-28 09:56:44

【 SPOJ - GRASSPLA】 Grass Planting (树链剖分+树状数组)的更多相关文章

  1. hdu 3966 Aragorn&&num;39&semi;s Story(树链剖分&plus;树状数组&sol;线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...

  2. Aragorn&&num;39&semi;s Story 树链剖分&plus;线段树 &amp&semi;&amp&semi; 树链剖分&plus;树状数组

    Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...

  3. 洛谷 P3384 【模板】树链剖分-树链剖分&lpar;点权&rpar;&lpar;路径节点更新、路径求和、子树节点更新、子树求和&rpar;模板-备注结合一下以前写的题目,懒得写很详细的注释

    P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...

  4. 【LuoguP3038&sol;&lbrack;USACO11DEC&rsqb;牧草种植Grass Planting】树链剖分&plus;树状数组【树状数组的区间修改与区间查询】

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

  5. HDU 3966 Aragorn&&num;39&semi;s Story 树链剖分&plus;树状数组 或 树链剖分&plus;线段树

    HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...

  6. bzoj1146整体二分&plus;树链剖分&plus;树状数组

    其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 #include<cstdio> #include<cstr ...

  7. HDU 5044 (树链剖分&plus;树状数组&plus;点&sol;边改查)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5044 题目大意:修改链上点,修改链上的边.查询所有点,查询所有边. 解题思路: 2014上海网赛的变 ...

  8. BZOJ 1146&colon; &lbrack;CTSC2008&rsqb;网络管理Network&lpar; 树链剖分 &plus; 树状数组套主席树 &rpar;

    树链剖分完就成了一道主席树裸题了, 每次树链剖分找出相应区间然后用BIT+(可持久化)权值线段树就可以完成计数. 但是空间问题很严重....在修改时不必要的就不要新建, 直接修改原来的..详见代码. ...

  9. hdu 3966 Aragorn&amp&semi;&num;39&semi;s Story&lpar;树链剖分&plus;树状数组&rpar;

    pid=3966" target="_blank" style="">题目链接:hdu 3966 Aragorn's Story 题目大意:给定 ...

  10. &lpar;简单&rpar; POJ 3321 Apple Tree,树链剖分&plus;树状数组。

    Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow ...

随机推荐

  1. C&num;的winform控件命名规范

    注:这里用红字标记的部分表示有重复出现,括号内为替代表示方案 1.标准控件 序号 控件类型简写 控件类型 1 btn Button 2 chk CheckBox 3 ckl CheckedListBo ...

  2. Codeforces Round &num;382 &lpar;Div&period; 2&rpar; 解题报告

    CF一如既往在深夜举行,我也一如既往在周三上午的C++课上进行了virtual participation.这次div2的题目除了E题都水的一塌糊涂,参赛时的E题最后也没有几个参赛者AC,排名又成为了 ...

  3. Google Code Jam 2014 Round 1B Problem B

    二进制数位DP,涉及到数字的按位与操作. 查看官方解题报告 #include <cstdio> #include <cstdlib> #include <cstring& ...

  4. OpenVPN中的几个和连接相关的Timer解析

    在OpenVPN中存在几个计时器,这些计时器限制着OpenVPN的一些特定行为的最长持续时间,如果设置不好,就会带来莫名其妙的断线问题,然而如何设置这些计数器也没有一个通用的方案,特定情况下不能太大也 ...

  5. &period;net TxetBox控件设置ReadOnly&equals;True后台取值问题

    1.为TxetBox添加onfocus=this.blur()进行模拟 2.通过 Request.From["TextBox"].Trim()取值; 3.后台CS文件设置TextB ...

  6. 使用ssh远程执行命令批量导出数据库到本地(转)

    前天正在跟前端的同事调试功能.服务器开好,模拟的玩家登录好,就在倒计时.这时突然运营的同事跑过来说要统计几个服务器玩家的一些情况,也就是需要从几个服的数据库导出部分玩家的数据.好吧,我看了一下时间,1 ...

  7. 【个人笔记】《知了堂》ajax的get及post请求

    ajax 执行步骤 // 步骤 设置事件 调用函数 创建一个XHR对象 打开ajax通道,链接服务器,配置请求信息和参数 发送数据 设置回调函数 服务器接受请求,处理请求,查询数据库,响应 及 返回数 ...

  8. Django--cookie(登录用)

    一.cookie产生原因 二.cookie的原理图 三.Django中如何设置/读取/删除cookie 四.Django中如何设置cookie的参数 一.cookie产生原因 HTTP协议的无状态保存 ...

  9. Python基础之集合

    一.定义: 二.基本操作: 三.运算: 交集&, 并集|, 补集-, 对称补集^, 子集<   超集> 四.集合推导式: 五.固定集合 frozenset 六.基本代码: # 1. ...

  10. Oarcle 之DML

    DML:数据操纵语言(Data Manipulation Language, DML)是SQL语言中,负责对数据库对象运行数据访问工作的指令集,以INSERT.UPDATE.DELETE三种指令为核心 ...