博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ3123:[SDOI2013]森林——题解
阅读量:6627 次
发布时间:2019-06-25

本文共 2663 字,大约阅读时间需要 8 分钟。

树上主席树操作方法看:

 ()

这题要动态树,显然不可能LCT套主席树啊。

那我们完全可以启发式合并一下主席树。

剩下的操作就很简单了。

(然而我debug两个小时才发现我n定义了两个emmmm)

#include
#include
#include
#include
#include
#include
using namespace std;const int N=8e4+10;inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X;}struct tree{ int l,r,sum;}tr[N*500];struct node{ int to,nxt;}edge[N*2];int a[N],b[N],rt[N],pool,n,m;int dep[N],anc[N][20],son[N];int cnt,head[N],fa[N],vis[N],tot;inline void add(int u,int v){ edge[++cnt].to=v;edge[cnt].nxt=head[u];head[u]=cnt;}inline void insert(int y,int &x,int l,int r,int p){ tr[x=++pool]=tr[y];tr[x].sum++; if(l==r)return; int mid=(l+r)>>1; if(p<=mid)insert(tr[y].l,tr[x].l,l,mid,p); else insert(tr[y].r,tr[x].r,mid+1,r,p);}inline int query(int nl,int nr,int nm,int nfm,int l,int r,int k){ if(l==r)return l; int delta=tr[tr[nl].l].sum+tr[tr[nr].l].sum-tr[tr[nm].l].sum-tr[tr[nfm].l].sum; int mid=(l+r)>>1; if(delta>=k)return query(tr[nl].l,tr[nr].l,tr[nm].l,tr[nfm].l,l,mid,k); else return query(tr[nl].r,tr[nr].r,tr[nm].r,tr[nfm].r,mid+1,r,k-delta);}inline void LSH(){ sort(b+1,b+m+1); m=unique(b+1,b+m+1)-b-1; for(int i=1;i<=n;i++){ a[i]=lower_bound(b+1,b+m+1,a[i])-b; } return;}inline int LCA(int i,int j){ if(dep[i]
=0;k--){ if(dep[anc[i][k]]>=dep[j])i=anc[i][k]; } if(i==j)return i; for(int k=16;k>=0;k--){ if(anc[i][k]!=anc[j][k])i=anc[i][k],j=anc[j][k]; } return anc[i][0];}int find(int x){ if(fa[x]==x)return x; return fa[x]=find(fa[x]);}void dfs(int u,int f,int root){ anc[u][0]=f; for(int k=1;k<=16;k++) anc[u][k]=anc[anc[u][k-1]][k-1]; son[root]++;dep[u]=dep[f]+1;fa[u]=root;vis[u]=1; insert(rt[f],rt[u],1,m,a[u]); for(int i=head[u];i;i=edge[i].nxt){ int v=edge[i].to; if(v!=f)dfs(v,u,root); } return;}int main(){ read(); n=read();int e=read(),T=read(),last=0; for(int i=1;i<=n;i++) a[i]=b[++m]=read(),fa[i]=i; LSH(); for(int i=1;i<=e;i++){ int x=read(),y=read(); add(x,y);add(y,x); } for(int i=1;i<=n;i++) if(!vis[i]){ dfs(i,0,++tot);fa[tot]=tot; } for(int i=1;i<=T;i++){ char ch=getchar(); while(ch!='Q'&&ch!='L')ch=getchar(); if(ch=='Q'){ int x=read()^last,y=read()^last,k=read()^last; int t=LCA(x,y),ft=anc[t][0]; printf("%d\n",last=b[query(rt[x],rt[y],rt[t],rt[ft],1,m,k)]); }else{ int x=read()^last,y=read()^last; add(x,y);add(y,x); int u=find(x),v=find(y); if(son[u]

+++++++++++++++++++++++++++++++++++++++++++

 +本文作者:luyouqi233。               +

 +欢迎访问我的博客:+

+++++++++++++++++++++++++++++++++++++++++++

 

转载于:https://www.cnblogs.com/luyouqi233/p/8510740.html

你可能感兴趣的文章
pku 1054 The Troublesome Frog 暴力+剪枝
查看>>
串行,并行,并发
查看>>
webservice测试工具
查看>>
Porting .Net RSA xml keys to Java
查看>>
检测 nginx.conf 是否配置正确
查看>>
最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和...
查看>>
测试妹子的呐喊:为什么总是收不到推送?
查看>>
linux NFS
查看>>
Jquery DataTable基本使用
查看>>
leetcode 674. Longest Continuous Increasing Subsequence
查看>>
Extensions in UWP Community Toolkit - SurfaceDialTextbox
查看>>
Golang 语言的单元测试和性能测试(也叫 压力测试)
查看>>
Java中CAS详解
查看>>
Linux系统实战项目——sudo日志审计
查看>>
Android Application Task Activities的关系
查看>>
浅谈CSS盒子模型
查看>>
实现iFrame自适应高度,原来很简单!
查看>>
get app id
查看>>
poj 3624 0/1背包暨0/1背包的学习
查看>>
[俗一下]世界500强公司的面试问题与答案提示 [转]
查看>>