模拟题,可以用树链剖分+线段树维护。

但是学了一个厉害的。。树状数组的区间修改与区间查询。。

分割线里面的是转载的:

--------------------------------------------------------------------------------

[ 3 ]  上面都不是重点……重点是树状数组的区间修改+区间查询 这个很好玩 其实也挺简单

首先依旧是引入delta数组 delta[i]表示区间 [i, n] 的共同增量 于是修改区间 [l, r] 时修改 delta[l] 和 delta[r + 1] 即可(就是差分的思路)

查询的时候是查询区间 [l, r] 的和 即sum[r] - sum[l - 1] 所以现在的问题是求sum[i]

 sum[i] = a[]+...+a[i] + delta[]*i + delta[]*(i - ) + delta[]*(i - )+...+delta[i]*   // a[i]为原始数组
= sigma( a[x] ) + sigma( delta[x] * (i + - x) )
= sigma( a[x] ) + (i + ) * sigma( delta[x] ) - sigma( delta[x] * x )
 

其中 sigma( a[x] ) 是可以预处理出来的 于是只需要维护 delta[x] 与 delta[x] * x 的前缀和(作为两个树状数组就可以了)

为了试验这个方法我专门去找了之前写线段树挂了好久的例题 = = codevs1082 线段树练习3

然后交树状数组的代码是 324ms 内存5M过了 线段树是1027ms 13M 如果去掉读入优化的话代码会更短。

--------------------------------------------------------------------------------------------------------------------------

转自:http://blog.csdn.net/qq_21841245/article/details/43956633

很好。。这题本机测系统暴栈了。。交上去才A。。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<ctime>
#include<queue>
using namespace std; const int N=*,S=,D=;
struct node{
int x,y,next;
}a[*N];
struct trnode{
int l,r,lc,rc,d;
}t[*N];
int n,m,len,num,first[N],dep[N],f[N][S],tot[N],zs[N],dfn[N],top[N],c0[N],c1[N],delta[N];
char s[]; void add(int x,int d)
{
for(int i=x;i<=n;i+=(i&(-i))) c0[i]+=d,c1[i]+=d*x;
} int getsum(int x)
{
int a0=,a1=;
for(int i=x;i>=;i-=(i&(-i))) a0+=c0[i],a1+=c1[i];
return a0*(x+)-a1;
} void ins(int x,int y)
{
a[++len].x=x;a[len].y=y;
a[len].next=first[x];first[x]=len;
} void dfs(int x,int fa)
{
dep[x]=dep[fa]+;
f[x][]=fa;
tot[x]=;
zs[x]=;
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(y==fa) continue;
dfs(y,x);
tot[x]+=tot[y];
if(zs[x]== || tot[y]>tot[zs[x]]) zs[x]=y;
}
} void find_top(int x,int fa)
{
dfn[x]=++num;
if(zs[x])
{
top[zs[x]]=top[x];
find_top(zs[x],x);
}
for(int i=first[x];i;i=a[i].next)
{
int y=a[i].y;
if(y==fa || y==zs[x]) continue;
top[y]=y;
find_top(y,x);
}
} int solve(int x,int y,int tmp)
{
int tx=top[x],ty=top[y],ans=;
while(tx!=ty)
{
if(dep[tx]<dep[ty]) swap(x,y),swap(tx,ty);
if(tmp==)
{
add(dfn[tx],);
add(dfn[x]+,-);
}
else ans+=getsum(dfn[x])-getsum(dfn[tx]-);
x=f[top[x]][];tx=top[x];
}
if(x==y) return ans;
else
{
if(dep[x]<dep[y]) swap(x,y);
if(tmp==)
{
add(dfn[y]+,);
add(dfn[x]+,-);
}
else ans+=getsum(dfn[x])-getsum(dfn[y]);
return ans;
}
} void lca_init()
{
for(int j=;j<=D;j++)
for(int i=;i<=n;i++)
f[i][j]=f[f[i][j-]][j-];
} int lca_query(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=D;i>=;i--)
{
if(f[x][i]==) continue;
if(dep[f[x][i]]>=dep[y]) x=f[x][i];
}
if(x==y) return x;
for(int i=D;i>=;i--)
{
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
}
return f[x][];
} int main()
{
freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
// freopen("grassplant.in","r",stdin);
// freopen("grassplant.out","w",stdout);
scanf("%d%d",&n,&m);
int x,y,z;len=;num=;
memset(first,,sizeof(first));
memset(f,,sizeof(f));
memset(c0,,sizeof(c0));
memset(c1,,sizeof(c1));
memset(dep,,sizeof(dep));
memset(tot,,sizeof(tot));
memset(zs,,sizeof(zs));
memset(dfn,,sizeof(dfn));
for(int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
ins(x,y);
ins(y,x);
}
dfs(,);
top[]=;find_top(,);
// for(int i=1;i<=n;i++)
// {
// printf("i = %d dep = %d zs = %d tot = %d dfn = %d top = %d\n",i,dep[i],zs[i],tot[i],dfn[i],top[i]);
// }
lca_init();
for(int i=;i<=m;i++)
{
scanf("%s",s);
scanf("%d%d",&x,&y);
if(s[]=='P')
{
z=lca_query(x,y);
solve(x,z,);
solve(y,z,);
}
else
{
printf("%d\n",solve(x,y,));
}
}
return ;
}

【LuoguP3038/[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. [USACO11DEC]牧草种植Grass Planting

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

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

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

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

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

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

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

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

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

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

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

  8. HYSBZ 4034 【树链剖分】+【线段树 】

    <题目链接> 题目大意: 有一棵点数为 N 的树,以点 1 为根,且树点有权值.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x ...

  9. BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector

    题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...

随机推荐

  1. PHP 签到,与时间获取,数组长度获取

    本文实例讲述了php实现签到功能的方法.分享给大家供大家参考,具体如下:首先我在数据库里建了两张表,一个是用户的积分表,一个是签到状态表,分来用来记录用户的积分数和先到状态 在用户签到状态表中我们有一 ...

  2. 生成以指定字符为开头的md5值(6位数字)

    以下脚本的功能是生成以指定字符为开头的md5值 #-*- coding:utf-8 -*- #脚本功能:生成以指定字符为开头的md5值(6位数字) import hashlib import rand ...

  3. java出现以下警告:WARN No appenders;WARN Please initialize the log4j的处理方法

    编译java或引用别的代码时出现以下警告: log4j:WARN No appenders could be found for logger (org.apache.zookeeper.ZooKee ...

  4. java-实用的sql语句

    一.在数据库创建表格的SQL语句 1,创建一个link表格,包含属性:lid  主键,title 标题,  imgpath 图片地址 , url  网址  , info 说明,  isshow 显示1 ...

  5. intelliJ IDEA最常用的快捷键

    一.使用相关快捷键 1.重写接口实现类:Ctrl+I 2.搜索:Shift+Shift   3.生成get或set方法快捷键:Alt+insert: 4.导入未实现的方法,强制类型转换:Alt+Ent ...

  6. Qt Pro文件与Qt模块启用

    看qt论坛中经常有人忘记 QT+=network 等语句.随便写写吧,或许对他人有帮助. 一.从哪开始呢 不妨先看个例子吧: #include <QtCore/QCoreApplication& ...

  7. table 标签 语法

  8. 前端基础:HTML标签(下)

    前端基础HTML标签(下) 1.表单 表单的功能主要用于向服务器传输数据,从而实现客户端与Web服务器的交互.表单能够包含input系列标签,比如:文本字段.复选框.单选按钮.提交按钮等:表单还包含t ...

  9. asp.net AES加密跟PHP的一致,将加密的2进制byte[]转换为16进制byte[] 的字符串获得

    <?php class AESUtil { public static function encrypt($input, $key) { $size = mcrypt_get_block_siz ...

  10. vdbench-自动化测试脚本

    #!/usr/bin/python # -*- coding:utf8 -*- import sys import commands TEST_CONF=""" hd=d ...