http://www.lydsy.com/JudgeOnline/problem.php?id=3730

点分树内对每个节点动态维护2颗线段树

线段树以距离为下标,城市的价值为权值

对于节点x的两棵线段树:

一棵维护 点分树中,x的子树 的贡献

一棵维护 点分树中,x对x的父节点的贡献

查询和修改时,暴力往上爬点分树

点分树保证了最多往上爬log次

查询x k时,先加上点分树内,x的子树中距离<=k的权值和,

再爬到x的父节点f,若x和f的距离为d,则加上f的子树中距离<=k-d的权值和,还要减去 x对f 贡献的<=k-d的权值和,因为这一部分在之前x的子树中算过了

以此类推 ,这就是第二棵线段树的作用

常数优化:

原代码总耗时:20.105 s

#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 100001 int n,a[N]; int front[N],nxt[N<<],to[N<<],tot; int all,root;
int siz[N],f[N]; bool vis[N]; int dep[N];
int fa[N][],dis[N][]; struct Segment
{
int cnt;
int rt[N];
int lc[N*],rc[N*],val[N*]; void Change(int &k,int l,int r,int x,int y)
{
if(!k) k=++cnt;
if(l==r)
{
val[k]+=y;
return;
}
int mid=l+r>>;
if(x<=mid) Change(lc[k],l,mid,x,y);
else Change(rc[k],mid+,r,x,y);
val[k]=val[lc[k]]+val[rc[k]];
} int Query(int k,int l,int r,int x)
{
if(!k) return ;
if(r<=x) return val[k];
int mid=l+r>>;
if(x<=mid) return Query(lc[k],l,mid,x);
else return val[lc[k]]+Query(rc[k],mid+,r,x);
} }tr,ftr; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
} void getroot(int x,int y)
{
siz[x]=; f[x]=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=y && !vis[to[i]])
{
getroot(to[i],x);
siz[x]+=siz[to[i]];
f[x]=max(f[x],siz[to[i]]);
}
f[x]=max(f[x],all-siz[x]);
if(f[x]<f[root]) root=x;
} void cal(int x,int ancestor,int father,int d)
{
int t;
for(int i=front[x];i;i=nxt[i])
{
t=to[i];
if(t!=father && !vis[t])
{
fa[t][++dep[t]]=ancestor;
dis[t][dep[t]]=d+;
cal(t,ancestor,x,d+);
}
}
} void build(int x)
{
vis[x]=true;
cal(x,x,,);
int tmp=all;
for(int i=front[x];i;i=nxt[i])
if(!vis[to[i]])
{
all=siz[to[i]];
if(all>siz[x]) all=tmp-siz[x];
root=;
getroot(to[i],);
build(root);
}
} void change(int x,int y)
{
tr.Change(tr.rt[x],,n-,,y);
int d;
for(int i=dep[x];i;--i)
{
ftr.Change(ftr.rt[fa[x][i+]],,n-,dis[x][i],y);
// printf("kk %d\n",dis[x][i]);
tr.Change(tr.rt[fa[x][i]],,n-,dis[x][i],y);
}
} int query(int x,int d)
{
int ans=tr.Query(tr.rt[x],,n-,d);
for(int i=dep[x];i;--i)
{
if(d-dis[x][i]>=) ans+=tr.Query(tr.rt[fa[x][i]],,n-,d-dis[x][i]);
if(d-dis[x][i]>=) ans-=ftr.Query(ftr.rt[fa[x][i+]],,n-,d-dis[x][i]);
}
return ans;
} void out(int x)
{
if(x>=) out(x/);
putchar(x%+'');
} int main()
{
freopen("wave.in","r",stdin);
freopen("wave.out","w",stdout);
int size = << ; // 256MB
char *p = (char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p));
int m;
read(n); read(m);
for(int i=;i<=n;++i) read(a[i]);
int u,v;
for(int i=;i<n;++i)
{
read(u); read(v);
add(u,v);
}
f[]=n+;
all=n;
getroot(,);
build(root);
for(int i=;i<=n;++i) fa[i][dep[i]+]=i;
for(int i=;i<=n;++i)
change(i,a[i]);
int ty,last=;
while(m--)
{
read(ty); read(u); read(v);
u^=last; v^=last;
if(!ty) last=query(u,v),out(last),printf("\n");
else change(u,v-a[u]),a[u]=v;
}
//printf("%d %d",tr.cnt,ftr.cnt);
return ;
}

原代码

1、原本线段树的操作封装在结构体里,拿出来,总耗时:16.934 s

2、动态开节点线段树 单点加:

在寻找x的路径上就进行加操作,而不是找到后再update

总耗时:14.357 s

3、数组改成结构体 总耗时:12.684 s

#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; #define N 100001 int n,a[N]; int front[N],nxt[N<<],to[N<<],tot; int all,root;
int siz[N],f[N]; bool vis[N]; int dep[N];
int fa[N][],dis[N][]; int rt[N<<],cnt; struct node
{
int lc,rc,val;
}tr[N*]; void Change(int &k,int l,int r,int x,int y)
{
if(!k) k=++cnt;
tr[k].val+=y;
if(l==r) return;
int mid=l+r>>;
if(x<=mid) Change(tr[k].lc,l,mid,x,y);
else Change(tr[k].rc,mid+,r,x,y); } int Query(int k,int l,int r,int x)
{
if(!k) return ;
if(r<=x) return tr[k].val;
int mid=l+r>>;
if(x<=mid) return Query(tr[k].lc,l,mid,x);
else return tr[tr[k].lc].val+Query(tr[k].rc,mid+,r,x);
} void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
} void getroot(int x,int y)
{
siz[x]=; f[x]=;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=y && !vis[to[i]])
{
getroot(to[i],x);
siz[x]+=siz[to[i]];
f[x]=max(f[x],siz[to[i]]);
}
f[x]=max(f[x],all-siz[x]);
if(f[x]<f[root]) root=x;
} void cal(int x,int ancestor,int father,int d)
{
int t;
for(int i=front[x];i;i=nxt[i])
{
t=to[i];
if(t!=father && !vis[t])
{
fa[t][++dep[t]]=ancestor;
dis[t][dep[t]]=d+;
cal(t,ancestor,x,d+);
}
}
} void build(int x)
{
vis[x]=true;
cal(x,x,,);
int tmp=all;
for(int i=front[x];i;i=nxt[i])
if(!vis[to[i]])
{
all=siz[to[i]];
if(all>siz[x]) all=tmp-siz[x];
root=;
getroot(to[i],);
build(root);
}
} void change(int x,int y)
{
Change(rt[x],,n-,,y);
int d;
for(int i=dep[x];i;--i)
{
Change(rt[fa[x][i+]+n],,n-,dis[x][i],y);
// printf("kk %d\n",dis[x][i]);
Change(rt[fa[x][i]],,n-,dis[x][i],y);
}
} int query(int x,int d)
{
int ans=Query(rt[x],,n-,d);
for(int i=dep[x];i;--i)
{
if(d-dis[x][i]>=) ans+=Query(rt[fa[x][i]],,n-,d-dis[x][i]);
if(d-dis[x][i]>=) ans-=Query(rt[fa[x][i+]+n],,n-,d-dis[x][i]);
}
return ans;
} void out(int x)
{
if(x>=) out(x/);
putchar(x%+'');
} int main()
{
int m;
read(n); read(m);
for(int i=;i<=n;++i) read(a[i]);
int u,v;
for(int i=;i<n;++i)
{
read(u); read(v);
add(u,v);
}
f[]=n+;
all=n;
getroot(,);
build(root);
for(int i=;i<=n;++i) fa[i][dep[i]+]=i;
for(int i=;i<=n;++i)
change(i,a[i]);
int ty,last=;
while(m--)
{
read(ty); read(u); read(v);
u^=last; v^=last;
if(!ty) last=query(u,v),out(last),printf("\n");
else change(u,v-a[u]),a[u]=v;
}
//printf("%d %d",tr.cnt,ftr.cnt);
return ;
}

bzoj千题计划244:bzoj3730: 震波的更多相关文章

  1. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  2. bzoj千题计划196:bzoj4826: [Hnoi2017]影魔

    http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...

  3. bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  4. bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...

  5. bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...

  6. bzoj千题计划304:bzoj3676: [Apio2014]回文串(回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3676 回文自动机模板题 4年前的APIO如今竟沦为模板,,,╮(╯▽╰)╭,唉 #include& ...

  7. bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹

    http://www.lydsy.com/JudgeOnline/problem.php?id=2244 每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数 pre_len ...

  8. bzoj千题计划278:bzoj4590: [Shoi2015]自动刷题机

    http://www.lydsy.com/JudgeOnline/problem.php?id=4590 二分 这么道水题 没long long WA了两发,没判-1WA了一发,二分写错WA了一发 最 ...

  9. bzoj千题计划250:bzoj3670: [Noi2014]动物园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3670 法一:KMP+st表 抽离nxt数组,构成一棵树 若nxt[i]=j,则i作为j的子节点 那么 ...

随机推荐

  1. I/HwPointEventFilter: do not support AFT because of no config

    I/HwPointEventFilter: do not support AFT because of no config 这是华为对系统做了修改,默认不打印日志,要改配置 在拨号界面输入:以下进入工 ...

  2. 【BZOJ1007】水平可见直线(单调栈)

    [BZOJ1007]水平可见直线(单调栈) 题解 Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的 ...

  3. log4j日志输出性能优化-缓存、异步

     转载 1.log4j已成为大型系统必不可少的一部分,log4j可以很方便的帮助我们在程序的任何位置输出所要打印的信息,便于我们对系统在调试阶段和正式运行阶段对问题分析和定位.由于日志级别的不同,对系 ...

  4. MyBatis的三层级联和二层缓存

           我们这里说的三层级联和二级缓存其实也是MyBatis映射器的知识点,只是因为比较难理解,所以单独拿出来讲解,下面是三层级联的内容:        我们知道,在数据库中包含着一对一,一对多 ...

  5. SpringMVC【参数绑定、数据回显、文件上传】

    前言 本文主要讲解的知识点如下: 参数绑定 数据回显 文件上传 参数绑定 我们在Controller使用方法参数接收值,就是把web端的值给接收到Controller中处理,这个过程就叫做参数绑定.. ...

  6. Lintcode223 Palindrome Linked List solution 题解

    [题目描述] Implement a function to check if a linked list is a palindrome. 设计一种方式检查一个链表是否为回文链表. [题目链接] w ...

  7. linux操作日志:远程登录设置

    想要远程linux服务器,首先需要在服务器上开通ssh服务,安装命令如下: sudo apt-get install openssh-server   在上图的提示中,输入“y”,继续等待安装,安装成 ...

  8. centos7上修改主机名

    centos7上修改主机名 2017-10-09   13:45:17 个人原创,转载请注明,否则追究法律责任 1,临时修改: 和centos5,centos6 一样,重启失效 2,永久修改: 命令: ...

  9. windows下安装mongoDB以及配置启动

    1.下载MongoDB的windows版本,有32位和64位版本,根据系统情况下载,下载地址:http://www.mongodb.org/downloads 2.解压缩至D:/mongodb即可 3 ...

  10. SSM 使用 mybatis 分页插件 pagehepler 实现分页

    使用分页插件的原因,简化了sql代码的写法,实现较好的物理分页,比写一段完整的分页sql代码,也能减少了误差性. Mybatis分页插件 demo 项目地址:https://gitee.com/fre ...