BZOJ 4448 主席树+树链剖分(在线)
来源:互联网 发布:网络直播平台怎么赚钱 编辑:程序博客网 时间:2024/06/06 18:14
为什么题解都是离线的…… (抄都没法抄)
搞一棵主席树
1 操作 新树上的当前节点设成1
2 操作 查max(i-xx-1,0)那棵树上这条路径上有多少个点是1
让你找经过了多少个点 查的时候用deep 搞出来就好了
//By SiriusRen#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 444444#define mem(x,y) memset(x,y,sizeof(x))int n,q,op,xx,yy,zz,first[N],v[N],next[N],tot,root,rt[N],ans;int size[N],fa[N],son[N],deep[N],top[N],change[N],back[N],cnt;struct Tree{int l,r,num;}tree[N*30];void Add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}void add(int x,int y){Add(x,y),Add(y,x);}void dfs(int x){ size[x]=1; for(int i=first[x];~i;i=next[i])if(v[i]!=fa[x]){ deep[v[i]]=deep[x]+1,fa[v[i]]=x,dfs(v[i]); size[x]+=size[v[i]]; if(size[son[x]]<size[v[i]])son[x]=v[i]; }}void dfs2(int x,int tp){ change[x]=++cnt,back[cnt]=x;top[x]=tp; if(son[x])dfs2(son[x],tp); for(int i=first[x];~i;i=next[i]) if(v[i]!=fa[x]&&v[i]!=son[x])dfs2(v[i],v[i]);}void push_up(int pos){tree[pos].num=tree[tree[pos].l].num+tree[tree[pos].r].num;}int build(int l,int r){ int pos=++cnt; if(l==r){return pos;} int mid=(l+r)>>1; tree[pos].l=build(l,mid),tree[pos].r=build(mid+1,r); return pos;}int insert(int o,int l,int r,int num){ int pos=++cnt;tree[pos]=tree[o]; if(l==r){tree[pos].num=1;return pos;} int mid=(l+r)>>1; if(mid>=num)tree[pos].l=insert(tree[o].l,l,mid,num); else tree[pos].r=insert(tree[o].r,mid+1,r,num); push_up(pos);return pos;}int query(int o,int l,int r,int L,int R){ if(l>=L&&r<=R)return tree[o].num; int mid=(l+r)>>1; if(mid<L)return query(tree[o].r,mid+1,r,L,R); else if(mid>=R)return query(tree[o].l,l,mid,L,R); else return query(tree[o].l,l,mid,L,R)+query(tree[o].r,mid+1,r,L,R);}int find(int x,int y,int wei){ int fx=top[x],fy=top[y],temp=0; while(fx!=fy){ if(deep[fx]<deep[fy])swap(x,y),swap(fx,fy); temp+=query(rt[wei],1,n,change[fx],change[x]),ans+=deep[x]-deep[fx]+1; x=fa[fx],fx=top[x]; } if(deep[x]<deep[y])swap(x,y); ans+=deep[x]-deep[y]+1; return temp+query(rt[wei],1,n,change[y],change[x]);}int main(){ mem(first,-1);scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&fa[i]); if(!fa[i])root=i;else add(i,fa[i]); } dfs(root),dfs2(root,root),cnt=0,rt[0]=build(1,n); scanf("%d",&q); for(int i=1;i<=q;i++){ scanf("%d",&op); if(op==1){ rt[i]=rt[i-1],ans=0; scanf("%d%d%d",&xx,&yy,&zz); zz=max(i-zz-1,0); printf("%d %d\n",ans,find(xx,yy,zz)); } else scanf("%d",&xx),rt[i]=insert(rt[i-1],1,n,change[xx]); }}
0 0
- BZOJ 4448 主席树+树链剖分(在线)
- bzoj 2588(树链剖分+主席树)
- BZOJ 4012 树链剖分+主席树
- bzoj 1803(主席树)
- bzoj 4448(LCA+主席树)(离线)
- bzoj 4448: [Scoi2015]情报传递 (树上主席树)
- bzoj 4012: [HNOI2015]开店 (树链剖分+主席树)
- bzoj 1878(莫队)(主席树)
- Bzoj 2653 middle(二分+主席树)
- bzoj 3524: [Poi2014]Couriers(主席树)
- bzoj 2653: middle (二分+主席树)
- bzoj 3207(主席树+hash)
- bzoj 2653(主席树+二分)
- bzoj 3123(主席树+启发式合并)
- bzoj 3524(主席树+二分)
- bzoj 1803(DFS序+主席树)
- bzoj 3932(主席树)
- BZOJ 2588 主席树
- 【erlang】【位语法】【Bit Syntax】
- 请设计一个算法,计算n的阶乘有多少个尾随零。 给定一个int n,请返回n的阶乘的尾零个数。保证n为正整数
- iOS强制横屏
- 数据结构(七) 图
- 树状菜单的运用
- BZOJ 4448 主席树+树链剖分(在线)
- Loginservlet
- 详解java定时任务
- 【笔记】HTML本地存储
- 插入排序—直接插入排序(Straight Insertion Sort)
- Android Eclipse 处理重构“AndroidPackageNameRefactoring”时捕获到异常
- userbean
- Oracle用户授权
- c# 调用log4net,解决中文字符显示乱码的问题