【BZOJ 4448】 [Scoi2015]情报传递|树链剖分|树套树
2016-03-23 07:24
447 查看
更简单的 主席树在这 http://blog.csdn.net/sxb_201/article/details/50960373
我写的是 普通线段树套权值线段树
虽然BZOJ过啦 但其实应该被卡一个点
内存比着数据开 一点不能多 一点不能少 不然第六个点BZOJ会爆
没想到主席树 是我弱
我写的是 普通线段树套权值线段树
虽然BZOJ过啦 但其实应该被卡一个点
内存比着数据开 一点不能多 一点不能少 不然第六个点BZOJ会爆
没想到主席树 是我弱
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; const int MAXN=200000+10; int tot,g[MAXN*2],nnext[MAXN*2],num[MAXN*2]; int fa[MAXN],top[MAXN],son[MAXN],depth[MAXN],size[MAXN],loc[MAXN]; int n,m; int team[MAXN],head,tail; void Add(int x,int y) { tot++; nnext[tot]=g[x]; g[x]=tot; num[tot]=y; } void Lp(int rt) { depth[rt]=1; team[++tail]=rt; while(head<tail) { int x=team[++head]; for(int i=g[x];i;i=nnext[i]) { int tmp=num[i]; depth[tmp]=depth[x]+1; fa[tmp]=x; team[++tail]=tmp; } } for(int i=n;i>=1;i--) { int x=team[i]; size[x]=1; for(int j=g[x];j;j=nnext[j]) { int tmp=num[j]; size[x]+=size[tmp]; if(size[tmp]>size[son[x]]) son[x]=tmp; } } loc[rt]=1; top[rt]=rt; for(int i=1;i<=n;i++) { int x=team[i]; int cnt=loc[x]; if(son[x]!=0) { loc[son[x]]=cnt+1; cnt+=size[son[x]]; top[son[x]]=top[x]; } for(int j=g[x];j;j=nnext[j]) { int tmp=num[j]; if(tmp!=son[x]) { loc[tmp]=cnt+1; cnt+=size[tmp]; top[tmp]=tmp; } } } } struct H { int L,R; int sum; }seg[MAXN*103]; int root[MAXN*4],rtc; void Ins(int now,int L,int R,int x) { seg[now].sum++; if(L==R) return ; int mid=(L+R)/2; if(x<=mid) { if(seg[now].L==0) seg[now].L=++rtc; Ins(seg[now].L,L,mid,x); } else { if(seg[now].R==0) seg[now].R=++rtc; Ins(seg[now].R,mid+1,R,x); } } void Change(int now,int L,int R,int x,int y) { if(root[now]==0) root[now]=++rtc; Ins(root[now],1,n,y); if(L==R) return ; int mid=(L+R)/2; if(x<=mid) Change(now*2,L,mid,x,y); else Change(now*2+1,mid+1,R,x,y); } int q(int now,int L,int R,int x) { if(now==0) return 0; if(R<=x) return seg[now].sum; int mid=(L+R)/2; if(x<=mid) return q(seg[now].L,L,mid,x); else return q(seg[now].L,L,mid,x)+q(seg[now].R,mid+1,R,x); } int Q(int now,int L,int R,int s,int t,int x) { if(s<=L&&R<=t) { return q(root[now],1,n,x); } int ans=0,mid=(L+R)/2; if(s<=mid) ans+=Q(now*2,L,mid,s,t,x); if(mid+1<=t) ans+=Q(now*2+1,mid+1,R,s,t,x); return ans; } int ans1,ans2; void QQ(int x,int y,int T) { ans1=ans2=0; while(top[x]!=top[y]) { if(depth[top[x]]<depth[top[y]]) swap(x,y); ans1+=loc[x]-loc[top[x]]+1; ans2+=Q(1,1,n,loc[top[x]],loc[x],T); x=fa[top[x]]; } if(depth[x]<depth[y]) swap(x,y); ans1+=loc[x]-loc[y]+1; ans2+=Q(1,1,n,loc[y],loc[x],T); } int b[MAXN]; int main() { int rt,x,y,z,opt; cin >>n; for(int i=1;i<=n;i++) { scanf("%d",&x); Add(x,i); if(x==0) rt=i; } Lp(rt); cin >>m; for(int i=1;i<=m;i++) { scanf("%d",&opt); if(opt==1) { scanf("%d %d %d",&x,&y,&z); QQ(x,y,i-z-1); printf("%d %d\n",ans1,ans2); } else { scanf("%d",&x); if(!b[x]) { Change(1,1,n,loc[x],i); b[x]=true; } } } return 0; }
相关文章推荐
- 【杭电oj】2277 - Change the ball(找规律)
- 【BZOJ 4443】 [Scoi2015]小凸玩矩阵|二分|最大匹配|匈牙利
- Using multiple LLVM versions on Ubuntu
- Uncovering the new RPC Client Access Service in Exchange 2010 (Part 3)
- Spring源码之bean的加载(五)准备创建bean
- 并查集
- Spring源码之bean的加载(四)获取单例
- 解决DRM找不到的问题。
- Facebook Phone Interview -- Move Zeros to Right (Easy)
- 嵌入式编程基础知识学习(1)
- 被解放的姜戈08 远走高飞
- Spring源码之bean的加载(三)从bean中获取对象
- Spring源码之bean的加载(二)获取单例bean
- Spring源码之bean的加载(一)
- 【杭电oj】2045 - 不容易系列之(3)—— LELE的RPG难题(递推)
- HoloLens开发手记-全息Hologram
- Raspkate - 基于.NET的可运行于树莓派的轻量型Web服务器
- CSS魔法堂:深入理解line-height和vertical-align
- 理解 virbr0 - 每天5分钟玩转 OpenStack(11)
- 理解 virbr0 - 每天5分钟玩转 OpenStack(11)