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

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

分割线里面的是转载的:

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

[ 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. 20145214实验一 Java开发环境的熟悉

    20145214实验一 Java开发环境的熟悉 使用JDK编译.运行简单的java程序 命令行下程序开发 在命令行下建立20145214实验目录,进入该目录后创建exp1目录. 把代码保存到exp1目 ...

  2. c# byte[] 保存图片

    1.用函数即可,File.WriteAllBytes(@"E:\123.bmp", pcBMPBuffer); 2.byte[]也可和image互相转化.

  3. Windows平台下安装.net coreclr

    .net coreclr 已经发布RC1版本,安装方法如下: 1.安装DNVM,DNVM是.net运行时管理器,负责管理所有版本的.net运行时(.net framework..net coreclr ...

  4. TCP源码—系统调用

    1.socket SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) sys_socket->sock_create-& ...

  5. 转 linux安装swoole扩展

    linux安装swoole扩展 发表于2年前(2014-09-03 14:05)   阅读(4404) | 评论(3) 7人收藏此文章, 我要收藏 赞2 上海源创会5月15日与你相约[玫瑰里],赶快来 ...

  6. phpcms找不到模板、空白模板的解决办法

    有时候会出现这个问题,尤其是在调试模板的过程中,不知道别的朋友的操作习惯.我的习惯是,先保留一份原始的模板.比如: index原版.html. 以便对比之用.但是呢,这样,往往会造成 找不到模板的情况 ...

  7. (转)centos6.5下Zabbix系列之Zabbix安装搭建及汉化

    最近在研究zabbix,在整理完成之后就有了写一下总结博客的想法,在我研究zabbix的时候给我很大帮助的是it你好,博客地址 http://itnihao.blog.51cto.com/他做的zab ...

  8. Python35 升级 pip

    使用pip安装插件的时候报错: You are using pip version 8.1.1, however version 9.0.1 is available.You should consi ...

  9. Swift学习与复习

    swift中文网 http://www.swiftv.cn http://swifter.tips/ http://objccn.io/ http://www.swiftmi.com/code4swi ...

  10. BZOJ 1042 硬币购物(背包DP+容斥原理)

    可以看出这是个多重背包,运用单调队列优化可以使每次询问达到O(s).这样总复杂度为O(s*tot). 会TLE. 因为改题的特殊性,每个硬币的币值是不变的,变的只是每次询问的硬币个数. 我们不妨不考虑 ...