【CF757G】Can Bash Save the Day?

题意:给你一棵n个点的树和一个排列${p_i}$,边有边权。有q个操作:

1 l r x:询问$\sum\limits_{i=l}^r dist(p_i,x)$
2 x:$swap(a_x,a_{x+1})$

$n,q\le 2\times 10^5$,强制在线。
题解:学到了新姿势:可持久化点分树。我们先将询问变成前缀相减的形式,然后对于每一个前缀都用一个点分树来维护,不难在$O(\log n)$的时间内处理掉一组询问。现在问题在于如何构建可持久化点分树。

首先,点分树的深度是$O(\log n)$的,所以我们在加入一个新点的时候可以新建这个点到根的那条链。而对于2操作,我们只需要重新构建第x棵点分树就好了。但是有一个问题,我们再新建一个点的时候需要复制这个点所有儿子的信息,但是一个点的儿子数量是$O(n)$级别的,怎么办?

这就需要我们对原树进行预处理,将多叉树转变为二叉树。具体方法:假如点x的儿子分别为$c_1,c_2,...c_k$,则我们新建k-2个点$t_1,t_2...t_{k-2}$,连边:$x-t_1,t_1-t_2,...,t_{k-3}-t_{k-2}$,$c_1-x,c_2-t_1,c_3-t_2,...c_{k-1}-t_{k-2},c_k-t_{k-2}$即可。总新建的点数显然不超过n。

那么我们在点分树上的每个点最多就只有3个儿子了。再记录一下从根走到每个点的路径就很容易处理了。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=200010;
typedef long long ll;
int n,m,N,cnt,Cnt,msk,mn,tot,root;
ll ans;
int to[maxn<<2],nxt[maxn<<2],head[maxn<<1],val[maxn<<2],To[maxn<<1],Nxt[maxn<<1],Head[maxn],Val[maxn<<1];
int p[maxn],siz[maxn<<1],Log[maxn<<2],d[maxn],vis[maxn<<1],dep[maxn<<1],pos[maxn<<1],rt[maxn];
ll md[20][maxn<<2],des[maxn<<1];
vector<int> step[maxn<<1];
struct node
{
int ch[3],cnt,org; ll s1,s2;
}s[maxn*60];
inline void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,nxt[cnt]=head[a],head[a]=cnt++;
}
inline void Add(int a,int b,int c)
{
To[Cnt]=b,Val[Cnt]=c,Nxt[Cnt]=Head[a],Head[a]=Cnt++;
}
void dfs1(int x,int fa)
{
for(int i=Head[x],last=0,tmp=0;i!=-1;i=Nxt[i]) if(To[i]!=fa)
{
tmp++;
if(tmp==1) add(x,To[i],Val[i]),add(To[i],x,Val[i]),last=x;
else if(tmp==d[x]-(x!=1)) add(last,To[i],Val[i]),add(To[i],last,Val[i]);
else
{
N++,add(last,N,0),add(N,last,0),last=N;
add(N,To[i],Val[i]),add(To[i],N,Val[i]);
}
}
for(int i=Head[x];i!=-1;i=Nxt[i]) if(To[i]!=fa) dfs1(To[i],x);
}
void dfs2(int x,int fa)
{
md[0][++pos[0]]=des[x],pos[x]=pos[0];
for(int i=head[x];i!=-1;i=nxt[i]) if(to[i]!=fa) des[to[i]]=des[x]+val[i],dfs2(to[i],x),md[0][++pos[0]]=des[x];
}
void getrt(int x,int fa)
{
siz[x]=1;
int tmp=0,i;
for(i=head[x];i!=-1;i=nxt[i]) if(!vis[to[i]]&&to[i]!=fa)
{
getrt(to[i],x),siz[x]+=siz[to[i]],tmp=max(tmp,siz[to[i]]);
}
tmp=max(tmp,tot-siz[x]);
if(tmp<mn) mn=tmp,root=x;
}
void solve(int x)
{
vis[x]=1,s[x].org=x;
for(int i=head[x];i!=-1;i=nxt[i]) if(!vis[to[i]])
{
tot=siz[to[i]],mn=1<<30,getrt(to[i],x),dep[root]=dep[x]+1;
for(int j=0;j<dep[x];j++) step[root].push_back(step[x][j]);
if(!s[x].ch[0]) s[x].ch[0]=root,step[root].push_back(0);
else if(!s[x].ch[1]) s[x].ch[1]=root,step[root].push_back(1);
else s[x].ch[2]=root,step[root].push_back(2);
solve(root);
}
}
inline ll lca(int a,int b)
{
a=pos[a],b=pos[b];
if(a>b) swap(a,b);
int k=Log[b-a+1];
return min(md[k][a],md[k][b-(1<<k)+1]);
}
inline ll dis(int a,int b)
{
return des[a]+des[b]-2*lca(a,b);
}
void insert(int x,int &y,int a,int b,int fa)
{
y=++tot;
int z=s[x].org;
memcpy(s[y].ch,s[x].ch,sizeof(s[y].ch)),s[y].org=z;
s[y].cnt=s[x].cnt+b,s[y].s1=s[x].s1+b*dis(z,a),s[y].s2=s[x].s2;
if(fa) s[y].s2+=b*dis(s[fa].org,a);
if(s[y].org==a) return ;
insert(s[x].ch[step[a][dep[z]]],s[y].ch[step[a][dep[z]]],a,b,y);
}
ll find(int x,int y)
{
int i,u;
ll ret=0;
for(i=0;i<dep[y];i++)
{
u=s[x].ch[step[y][i]];
ret+=(s[x].cnt-s[u].cnt)*dis(s[x].org,y)+(s[x].s1-s[u].s2);
x=u;
}
return ret+s[x].s1;
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int main()
{
//freopen("cf757G.in","r",stdin);
N=n=rd(),m=rd(),msk=(1<<30)-1;
int i,j,a,b,c;
for(i=1;i<=n;i++) p[i]=rd();
memset(head,-1,sizeof(head)),memset(Head,-1,sizeof(Head));
for(i=1;i<n;i++) a=rd(),b=rd(),c=rd(),Add(a,b,c),Add(b,a,c),d[a]++,d[b]++;
dfs1(1,0),dfs2(1,0);
for(i=2;i<=pos[0];i++) Log[i]=Log[i>>1]+1;
for(j=1;(1<<j)<=pos[0];j++) for(i=1;i+(1<<j)-1<=pos[0];i++) md[j][i]=min(md[j-1][i],md[j-1][i+(1<<(j-1))]);
tot=N,mn=1<<30,getrt(1,0),rt[0]=root,solve(root);
tot=N;
for(i=1;i<=n;i++)
insert(rt[i-1],rt[i],p[i],1,0);
for(i=1;i<=m;i++)
{
if(rd()==1)
{
a=rd()^ans,b=rd()^ans,c=rd()^ans;
ans=find(rt[b],c)-find(rt[a-1],c);
printf("%lld\n",ans);
ans&=msk;
}
else
{
a=rd()^ans;
insert(rt[a-1],rt[a],p[a],0,0),swap(p[a],p[a+1]),insert(rt[a],rt[a],p[a],1,0);
}
}
return 0;
}//5 5 4 5 1 3 2 4 2 4 1 3 9 4 1 4 4 5 2 1 1 5 4 1 22 20 20 2 38 2 39 1 36 38 38

【CF757G】Can Bash Save the Day? 可持久化点分树的更多相关文章

  1. CF757G Can Bash Save the Day?

    CF757G Can Bash Save the Day? #include<bits/stdc++.h> #define RG register #define IL inline #d ...

  2. [Codeforces757G]Can Bash Save the Day?——动态点分治(可持久化点分树)

    题目链接: Codeforces757G 题目大意:给出一棵n个点的树及一个1~n的排列pi,边有边权,有q次操作: 1 l r x 求 $\sum\limits_{i=l}^{r}dis(p_{i} ...

  3. 51nod 1295 XOR key 可持久化01字典树

    题意 给出一个长度为\(n\)的正整数数组\(a\),再给出\(q\)个询问,每次询问给出3个数,\(L,R,X(L<=R)\).求\(a[L]\)至\(a[R]\)这\(R-L+1\)个数中, ...

  4. HDU 6191 2017ACM/ICPC广西邀请赛 J Query on A Tree 可持久化01字典树+dfs序

    题意 给一颗\(n\)个节点的带点权的树,以\(1\)为根节点,\(q\)次询问,每次询问给出2个数\(u\),\(x\),求\(u\)的子树中的点上的值与\(x\)异或的值最大为多少 分析 先dfs ...

  5. FHQ Treap及其可持久化与朝鲜树式重构

    FHQ Treap,又称无旋treap,一种不基于旋转机制的平衡树,可支持所有有旋treap.splay等能支持的操作(只有在LCT中会比splay复杂度多一个log).最重要的是,它是OI中唯一一种 ...

  6. 洛谷P3919 【模板】可持久化数组 [主席树]

    题目传送门 可持久化数组 题目描述 如题,你需要维护这样的一个长度为 $N$ 的数组,支持如下几种操作 在某个历史版本上修改某一个位置上的值 访问某个历史版本上的某一位置的值 此外,每进行一次操作(对 ...

  7. P5283 [十二省联考2019]异或粽子 可持久化01Trie+线段树

    $ \color{#0066ff}{ 题目描述 }$ 小粽是一个喜欢吃粽子的好孩子.今天她在家里自己做起了粽子. 小粽面前有 \(n\) 种互不相同的粽子馅儿,小粽将它们摆放为了一排,并从左至右编号为 ...

  8. luogu 2483 K短路 (可持久化左偏树)

    题面: 题目大意:给你一张有向图,求1到n的第k短路 $K$短路模板题 假设整个图的边集为$G$ 首先建出以点$n$为根的,沿反向边跑的最短路树,设这些边构成了边集$T$ 那么每个点沿着树边走到点$n ...

  9. luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树

    LINK:字符串树 先说比较简单的正解.由于我没有从最简单的考虑答案的角度思考 所以... 下次还需要把所有角度都考察到. 求x~y的答案 考虑 求x~根+y~根-2*lca~根的答案. 那么问题变成 ...

随机推荐

  1. WebGL Matrix4(4*4矩阵库)

    Matrix4是由<<WebGL编程指南>>作者写的提供WebGL的4*4矩阵操作的方法库,简化我们编写的代码.源代码共享地址,点击链接:Matrix4源代码. 下面罗列了Ma ...

  2. C# toolstrip 上添加DateTimePicker Control控件

    private void AddDTPtoToolstrip( n){DateTimePicker dtp = DateTimePicker;dtp.Width = 110;dtp.Format = ...

  3. Java并发编程、内存模型与Volatile

    http://www.importnew.com/24082.html  volatile关键字 http://www.importnew.com/16142.html  ConcurrentHash ...

  4. [AX]AX2012 Interaction class

    Ax2012 Client的form如果属性FormTemplate设置为DetailsPage或者ListPage,则必须同时设置属性InteractionClass为相应的Interaction类 ...

  5. iOS Runloop的超级讲解

    这是目前看过的最好的一片中文讲解RunLoop的文章,推荐给大家看一下,原文链接:http://blog.ibireme.com/2015/05/18/runloop/ https://segment ...

  6. 入门常用SQL及官方文档的使用

    SQL语句基础理论 SQL是操作和检索关系型数据库的标准语言,标准SQL语句可用于操作关系型数据库. 5大主要类型: ①DQL(Data Query Language,数据查询语言)语句,主要由于se ...

  7. redis make错误处理

    cc: ../deps/hiredis/libhiredis.a: No such file or directory cc: ../deps/lua/src/liblua.a: No such fi ...

  8. 使用powerdesigner连接MySQL并设置逆向工程图文教程

    我用的是Win7 x64的系统,安装了64为的mysql-connector-odbc-5.1.10-winx64.msi在数据源中test正常,但在powerdesigner连接Mysql总是弹出“ ...

  9. 【安全开发】python安全编码规范

    申明:本文非笔者原创,原文转载自:https://github.com/SecurityPaper/SecurityPaper-web/blob/master/_posts/2.SDL%E8%A7%8 ...

  10. 一句话木马:ASP篇

    ASP一句话木马收集: <%eval request("chopper")%> <%execute request("chopper")%&g ...