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

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

分割线里面的是转载的:

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

[ 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. TensorFlow安装解惑

    本文整理自网络,若有侵犯请告知. 1.安装环境 目前TensorFlow社区推荐的环境是Ubuntu, 但是TensorFlow同时支持Mac,Windows上的安装部署. 2.关于GPU版本 因为深 ...

  2. 记一次dll强命名冲突事件

    一  问题的出现 现在要做一个net分布式平台,平台涉及多个服务之间调用问题,最基础的莫过于sso.由于我们的sso采用了wcf一套私有框架实现,另外一个webapi服务通过接口调用sso服务.由于s ...

  3. SVM之问题形式化

    >>>SVM之问题形式化 SVM之对偶问题 SVM之核函数 SVM之解决线性不可分 写在SVM之前——凸优化与对偶问题 SVM内容繁多,打算用五篇文章来记述.SVM之问题形式化描述给 ...

  4. HDU 2117 Just a Numble

    http://acm.hdu.edu.cn/showproblem.php?pid=2117 Problem Description Now give you two integers n m, yo ...

  5. Httpd主配置文件httpd.conf 详解

    Apache的主配置文件:/etc/httpd/conf/httpd.conf默认站点主目录:/var/www/html/Apache服务器的配置信息全部存储在主配置文件/etc/httpd/conf ...

  6. MHDD工具使用简写

    检查硬盘,建议接主板一口,DOS工具箱输入mhdd回车进入界面 输入硬盘接口号(这里不固定) 按F4是进行硬盘扫描,按两次就开始,按方向键进行快进 Mhdd界面输入 erase命令:擦除指定扇区范围内 ...

  7. 关闭win7/Server 2008非正常关机启动自动修复功能

    命令提示符下输入 bcdedit /set {default} bootstatuspolicy ignoreallfailures bcdedit /set {current} recoveryen ...

  8. 关键系统的JVM参数推荐

    1. 性能篇 1.1 建议的性能参数 1. 取消偏向锁: -XX:-UseBiasedLocking JDK1.6开始默认打开的偏向锁,会尝试把锁赋给第一个访问它的线程,取消同步块上的synchron ...

  9. imshow(A,[])和imshow(A)的区别

    imshow的用法: IMSHOW Display image. IMSHOW(I,N) displays the intensity image I with N discrete levels o ...

  10. javascript标准对象与包装对象

    javascript标准对象与包装对象 标准对象 在JavaScript的世界里,一切都是对象. 但是某些对象还是和其他对象不太一样.为了区分对象的类型,我们用typeof操作符获取对象的类型,它总是 ...