考虑这样一个问题:一棵树初始全是白点,有两种操作:把一个点染黑;询问某点到所有黑点的距离之和。

  注意到树上两点x和y的距离为depth[x]+depth[y]-depth[lca(x,y)]*2。要求出上面的东西,depth[x]+depth[y]可以很简单的算出来,关键在于depth[lca(x,y)]。这一部分实质上是x到根的路径和y到根的路径重合的部分。那么我们可以树剖,在修改的时候,把该点到根的路径全部+1(其实是1单位,具体到每个点是其到父亲的那条边的长度),查询时查这个点到根的权值和就好了。

  然后回到本题。无修改查询某个区间很容易想到主席树,那么按照点权从小到大染黑就是上面那个题,用主席树记录一下答案。每次需要在主席树上修改logn个区间,那么复杂度是log^2的。注意查询时不能下传标记,否则空间爆炸。

  这个做法并没有用到度数<=3的性质,要用的话可以动态点分,写不动。

  对着树剖和主席树的部分调了好长时间,感觉非常正确,最后发现离散化出问题了……没救。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 200010
int n,m,q,t=,a[N],c[N],p[N],b[N],deep[N];
int dfn[N],fa[N],top[N],id[N],size[N],son[N],cnt=;
long long lastans=,tot[N];
struct data{int to,nxt,len;
}edge[N<<];
int root[N],sum[N],sz[N];
struct data2{int l,r,tag;long long x;
}tree[N<<];
void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
bool cmp(const int&x,const int&y)
{
return a[x]<a[y];
}
void dfs1(int k)
{
size[k]=;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k])
{
deep[edge[i].to]=deep[k]+edge[i].len;
fa[edge[i].to]=k;
dfs1(edge[i].to);
size[k]+=size[edge[i].to];
if (size[edge[i].to]>size[son[k]]) son[k]=edge[i].to;
}
}
void dfs2(int k,int from)
{
top[k]=from;id[k]=++cnt;dfn[cnt]=k;
if (son[k]) dfs2(son[k],from);
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k]&&edge[i].to!=son[k])
dfs2(edge[i].to,edge[i].to);
}
void add(int &k,int l,int r,int x,int y)
{
tree[++cnt]=tree[k];k=cnt;
tree[k].x+=sum[y]-sum[x-];
if (l==x&&r==y){tree[k].tag++;return;}
int mid=l+r>>;
if (y<=mid) add(tree[k].l,l,mid,x,y);
else if (x>mid) add(tree[k].r,mid+,r,x,y);
else add(tree[k].l,l,mid,x,mid),add(tree[k].r,mid+,r,mid+,y);
}
long long query(int k,int l,int r,int x,int y,int tag)
{
if (l==x&&r==y) return tree[k].x+1ll*(sum[y]-sum[x-])*tag;
tag+=tree[k].tag;
int mid=l+r>>;
if (y<=mid) return query(tree[k].l,l,mid,x,y,tag);
else if (x>mid) return query(tree[k].r,mid+,r,x,y,tag);
else return query(tree[k].l,l,mid,x,mid,tag)+query(tree[k].r,mid+,r,mid+,y,tag);
}
void modify(int i,int x)
{
while (x)
{
add(root[i],,n,id[top[x]],id[x]);
x=fa[top[x]];
}
}
long long getans(int r,int l,int x)
{
long long s=1ll*deep[x]*(sz[r]-sz[l])+tot[r]-tot[l];
while (x)
{
s-=query(root[r],,n,id[top[x]],id[x],)-query(root[l],,n,id[top[x]],id[x],)<<;
x=fa[top[x]];
}
return s;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj4012.in","r",stdin);
freopen("bzoj4012.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),q=read(),m=read();
for (int i=;i<=n;i++) c[i]=a[i]=read(),b[i]=i;
sort(b+,b+n+,cmp);
sort(c+,c+n+);
int u=unique(c+,c+n+)-c;
for (int i=;i<n;i++)
{
int x=read(),y=read(),z=read();
addedge(x,y,z),addedge(y,x,z);
}
dfs1();
dfs2(,);
cnt=;
for (int i=;i<=n;i++) sum[i]=sum[i-]+deep[dfn[i]]-deep[fa[dfn[i]]];
for (int i=;i<=n;i++)
{
int x=lower_bound(c+,c+u,a[b[i]])-c;
root[x]=root[x-];tot[x]=tot[x-];
modify(x,b[i]);tot[x]+=deep[b[i]];
while (a[b[i+]]==a[b[i]]) i++,modify(x,b[i]),tot[x]+=deep[b[i]];
sz[x]=i;
}
for (int i=;i<=q;i++)
{
int x=read(),w=read(),v=read();
int l=min((w+lastans)%m,(v+lastans)%m),r=max((w+lastans)%m,(v+lastans)%m);
l=lower_bound(c+,c+u,l)-c,r=upper_bound(c+,c+u,r)-c-;
lastans=getans(r,l-,x);
printf(LL,lastans);
}
return ;
}

BZOJ4012 HNOI2015开店(树链剖分+主席树)的更多相关文章

  1. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  2. Codechef FIBTREE 树链剖分 主席树 LCA 二次剩余 快速幂

    原文链接https://www.cnblogs.com/zhouzhendong/p/CC-FIBTREE.html 题目传送门 - CC-FIBTREE 题意 给定一个有 $n$ 个节点,初始点权都 ...

  3. BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...

  4. bzoj 4448 [Scoi2015]情报传递 (树链剖分+主席树)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4448 题面: Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络 ...

  5. BZOJ 4448: [Scoi2015]情报传递 树链剖分 主席树

    4448: [Scoi2015]情报传递 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4448 Description 奈特公司是一个巨 ...

  6. [GDOI2016][树链剖分+主席树]疯狂动物城

    题面 Description Nick 是只在动物城以坑蒙拐骗为生的狐狸,儿时受到偏见的伤害,放弃了自己的理想.他被兔子 Judy 设下圈套,被迫与她合作查案,而卷入意想不到的阴谋,历尽艰险后成为搭档 ...

  7. HDU 5111 Alexandra and Two Trees 树链剖分 + 主席树

    题意: 给出两棵树,每棵树的节点都有一个权值. 同一棵树上的节点的权值互不相同,不同树上节点的权值可以相同. 要求回答如下询问: \(u_1 \, v_1 \, u_2 \, v_2\):询问第一棵树 ...

  8. 5.15 牛客挑战赛40 E 小V和gcd树 树链剖分 主席树 树状数组 根号分治

    LINK:小V和gcd树 时限是8s 所以当时好多nq的暴力都能跑过. 考虑每次询问暴力 跳父亲 这样是nq的 4e8左右 随便过. 不过每次跳到某个点的时候需要得到边权 如果直接暴力gcd的话 nq ...

  9. BZOJ3531 SDOI2014 旅行 - 树链剖分,主席树

    题意:给定一棵树,树上每个点有权值和类型.支持:修改某个点的类型:修改某个点的权值:询问某条链上某个类型的点的和/最大值.点数/类型数/询问数<=100000. 分析: 树链剖分,对每个类型的点 ...

随机推荐

  1. java Arrays数组

    1.java.util.Arrays 工具类的使用Arrays 类中的常用方法1) toString()打印数组2) equals()比较两个数组是否相同3) copyOf(…)复制指定的数组 (效率 ...

  2. xrange 和range的区别

    >>> xrange(5)xrange(5)>>> list(xrange(5))[0, 1, 2, 3, 4]>>> xrange(1,5)xr ...

  3. 使用Windows API进行串口编程

    使用Windows API进行串口编程   串口通信一般分为四大步:打开串口->配置串口->读写串口->关闭串口,还可以在串口上监听读写等事件.1.打开和关闭串口Windows中串口 ...

  4. linux应用编程之进程间同步

    一.描述 在操作系统中,异步并发执行环境下的一组进程,因为相互制约关系,进而互相发送消息.互相合作.互相等待,使得各进程按一定的顺序和速度执行,称为进程间的同步.具有同步关系的一组并发进程,称为合作进 ...

  5. 3.2《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——检查文件开始与结尾

    检查文件两个互补的命令是head 和tail, 它们分别用于查看文件的开始(头部)和结束(尾部).head命令展示了文件的前10行.(Listing 11). ##Listing 11: 查看示例文件 ...

  6. POJ3301 Texas Trip 计算几何、随机化贪心

    传送门--Vjudge 三分写法似乎有问题,可以去Udebug上看Morass的\(666\)个测试点的数据,我的乱搞有很多比正解答案小,但还是能在SPOJ和POJ过,可见数据之水. 可以对正方形的角 ...

  7. Zookeeper-集群与单机实践

    我用的是linux,CentOS7.3,zookeeper的版本是3.4.6,工具XShell.上传zookeeper的压缩包后我们开始操作. 集群模式: 1.解压zookeeper,路径随意 tar ...

  8. .Net版本依赖之坑引发的搜查

    前言 今天上午,一个客户反馈XX消息没有推送到第三方链接.于是我查看了推送日志列表,并没有今天的.接着登录服务器查询文件日志,看到了记录.我们的代码步骤是消息先推送到消息队列,消费消息队列时,记录文件 ...

  9. Visual Studio 2019 Serial Keys

    Visual Studio 2019 Enterprise BF8Y8-GN2QH-T84XB-QVY3B-RC4DF Visual Studio 2019 Professional NYWVH-HT ...

  10. 【nodejs】让nodejs像后端mvc框架(asp.net mvc)一样处理请求--参数自动映射篇(6/8)

    文章目录 前情概要 路由.action的扫描.发现.注册搞定之后,后来我发现在我们的action里面获取参数往往都是通过request对象来一个一个获取.同样的一行代码我们不厌其烦的重复写了无数次.遂 ...