国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > 综合技术 > SPOJ QTREE 1-3题解

SPOJ QTREE 1-3题解

来源:程序员人生   发布时间:2016-03-10 14:33:18 阅读次数:2145次

昨天刷了几道QTREE,感觉码长萌萌哒;

但是由于本人太弱刷不动QTREE4,动态点分治并没有理解上去的能力;

因而暂且弃疗啦,在这里写点题解扔点代码吧;


QTREE1

题意:

给出1个有边权的树;

操作1:改变某条边权;

操作2:查询两点之间路径上最大边权;


题解:

树链剖分的姿式还是挺裸的,想了想没有甚么好办法码了1发;

普通的树链剖分保护树上路径,加1个线段树,时间复杂度O(nlog^2n);


QTREE2

题意:

给出1个有边权的树;

操作1:查询两点之间路径长度;

操作2:查询两点之间路径上经过的第K个点;


题解:

由于是无修的,操作1可以方便的用倍增LCA弄;

操作2在跑过1次LCA以后,YY1下也就是从某个点向上K步之类的东西;

时间复杂度O(nlogn),手滑打错1个字母调了好久;


QTREE3

题意:

给出1个有点权的树;

每次查询某个点子树中第K小点权是哪一个点;


题解:

操作只有1种,子树保护直接在DFS序上就能够了;

第K大用主席树来保护,时间复杂度O(nlogn),空间复杂度O(nlogn);

SPOJ的1.5G内存真是太爽啦 (然后到BZOJ上就MLE了)


代码:


QTREE1:


#include #include #include#define N 11000 #define lson l,mid,no<<1 #define rson mid+1,r,no<<1|1 using namespace std; int next[N<<1],to[N<<1],len[N<<1],head[N],ce; int n,X[N],Y[N],V[N]; int val[N],deep[N],fa[N],size[N],son[N],top[N],p[N],tot; int ma[N<<2]; char op[20]; void Pushup(int no) { ma[no]=max(ma[no<<1],ma[no<<1|1]); } void update(int l,int r,int no,int k,int val) { if(l==r) ma[no]=val; else { int mid=l+r>>1; if(k<=mid) update(lson,k,val); else update(rson,k,val); Pushup(no); } } int query(int l,int r,int no,int st,int en) { if(st<=l&&r<=en) return ma[no]; else { int mid=l+r>>1; if(en<=mid) return query(lson,st,en); else if(st>mid) return query(rson,st,en); else return max(query(lson,st,en),query(rson,st,en)); } } void add(int x,int y,int v) { to[++ce]=y; len[ce]=v; next[ce]=head[x]; head[x]=ce; } void dfs1(int x) { deep[x]=deep[fa[x]]+1; size[x]=1; for(int i=head[x];i;i=next[i]) { if(to[i]!=fa[x]) { fa[to[i]]=x; val[to[i]]=len[i]; dfs1(to[i]); size[x]+=size[to[i]]; if(size[to[i]]>size[son[x]]) son[x]=to[i]; } } } void dfs2(int x,int t) { top[x]=t; p[x]=++tot; update(1,n,1,p[x],val[x]); if(son[x]) dfs2(son[x],t); for(int i=head[x];i;i=next[i]) if(to[i]!=fa[x]&&to[i]!=son[x]) dfs2(to[i],to[i]); } void init() { memset(head,0,sizeof(head)); memset(son,0,sizeof(son)); ce=tot=0; } int find(int x,int y) { int ret=0; while(top[x]!=top[y]) { if(deep[top[x]]deep[Y[i]]?X[i]:Y[i]; while(scanf("%s",op)!=EOF&&op[0]!=D) { scanf("%d%d",&x,&y); if(op[0]==C) { val[X[x]]=y; update(1,n,1,p[X[x]],y); } else { printf("%d ",find(x,y)); } } } return 0; }


QTREE2:


#include #include #include#define N 110000 using namespace std; int next[N<<1],to[N<<1],val[N<<1],head[N],ce; int fa[N][20],dis[N][20],deep[N]; char op[20]; void add(int x,int y,int v) { to[++ce]=y; val[ce]=v; next[ce]=head[x]; head[x]=ce; } void dfs(int x) { int i; deep[x]=deep[fa[x][0]]+1; for(i=1;fa[x][i⑴];i++) fa[x][i]=fa[fa[x][i⑴]][i⑴], dis[x][i]=dis[x][i⑴]+dis[fa[x][i⑴]][i⑴]; for(i=head[x];i;i=next[i]) { if(to[i]!=fa[x][0]) { fa[to[i]][0]=x; dis[to[i]][0]=val[i]; dfs(to[i]); } } } int DIST(int x,int y) { if(deep[x]=0) { if(deep[fa[x][t]]>=deep[y]) ret+=dis[x][t],x=fa[x][t]; t--; } if(x==y) return ret; t=15; while(t>=0) { if(fa[x][t]!=fa[y][t]) ret+=dis[x][t],x=fa[x][t], ret+=dis[y][t],y=fa[y][t]; t--; } return ret+dis[x][0]+dis[y][0]; } int KTH(int x,int y,int k) { int t=15,retx=0,rety=0,tx=x,ty=y; if(deep[tx]>deep[ty]) { while(t>=0) { if(deep[fa[tx][t]]>=deep[ty]) retx+=(1<=0) { if(deep[fa[ty][t]]>=deep[tx]) rety+=(1<=0) { if(fa[tx][t]!=fa[ty][t]) retx+=(1<=k⑴) { k--; t=15; while(t>=0) { if(k&1<=0) { if(k&1<
QTREE3:


#include #include #include#define N 110000 #define M 10000000 #define lson l,mid,ls[no] #define rson mid+1,r,rs[no] using namespace std; int next[N<<1],to[N<<1],head[N],ce; int val[N],dis[N],which[N]; int n,L[N],R[N],tim; int size[M],ls[M],rs[M],root[N],tot; void Insert(int l,int r,int &no,int val) { int p=++tot; ls[p]=ls[no],rs[p]=rs[no],size[p]=size[no]; no=p; size[no]++; if(l==r) return ; int mid=l+r>>1; if(val<=mid) Insert(lson,val); else Insert(rson,val); } int query(int l,int r,int nol,int nor,int k) { if(l==r) return l; else { int mid=l+r>>1; if(k<=size[ls[nor]]-size[ls[nol]]) return query(l,mid,ls[nol],ls[nor],k); else return query(mid+1,r,rs[nol],rs[nor],k-size[ls[nor]]+size[ls[nol]]); } } void add(int x,int y) { to[++ce]=y; next[ce]=head[x]; head[x]=ce; } void dfs(int x,int pre) { L[x]=++tim; root[tim]=root[tim⑴]; Insert(1,n,root[tim],val[x]); for(int i=head[x];i;i=next[i]) if(to[i]!=pre) dfs(to[i],x); R[x]=tim; } int main() { int m,i,j,k,x,y; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",val+i); dis[i]=val[i]; } sort(dis+1,dis+n+1); for(i=1;i<=n;i++) { val[i]=lower_bound(dis+1,dis+n+1,val[i])-dis; which[val[i]]=i; } for(i=1;i


生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生