http://www.lydsy.com/JudgeOnline/problem.php?id=3123

https://www.luogu.org/problemnew/show/P3302

树上主席树操作方法看:http://www.cnblogs.com/luyouqi233/p/8159528.html

BZOJ2588:Count on a tree

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

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

剩下的操作就很简单了。

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

#include<cstdio>
#include<cmath>
#include<cstring>
#include<cctype>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=8e4+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct tree{
int l,r,sum;
}tr[N*];
struct node{
int to,nxt;
}edge[N*];
int a[N],b[N],rt[N],pool,n,m;
int dep[N],anc[N][],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)>>;
if(p<=mid)insert(tr[y].l,tr[x].l,l,mid,p);
else insert(tr[y].r,tr[x].r,mid+,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)>>;
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+,r,k-delta);
}
inline void LSH(){
sort(b+,b+m+);
m=unique(b+,b+m+)-b-;
for(int i=;i<=n;i++){
a[i]=lower_bound(b+,b+m+,a[i])-b;
}
return;
}
inline int LCA(int i,int j){
if(dep[i]<dep[j])swap(i,j);
for(int k=;k>=;k--){
if(dep[anc[i][k]]>=dep[j])i=anc[i][k];
}
if(i==j)return i;
for(int k=;k>=;k--){
if(anc[i][k]!=anc[j][k])i=anc[i][k],j=anc[j][k];
}
return anc[i][];
}
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][]=f;
for(int k=;k<=;k++)
anc[u][k]=anc[anc[u][k-]][k-];
son[root]++;dep[u]=dep[f]+;fa[u]=root;vis[u]=;
insert(rt[f],rt[u],,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=;
for(int i=;i<=n;i++)
a[i]=b[++m]=read(),fa[i]=i;
LSH();
for(int i=;i<=e;i++){
int x=read(),y=read();
add(x,y);add(y,x);
}
for(int i=;i<=n;i++)
if(!vis[i]){
dfs(i,,++tot);fa[tot]=tot;
}
for(int i=;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][];
printf("%d\n",last=b[query(rt[x],rt[y],rt[t],rt[ft],,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]<son[v]){
swap(u,v);
swap(x,y);
}
dfs(y,x,u);
}
}
return ;
}

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

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

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

最新文章

  1. 注意kvm在安装虚机的时候不能把存放虚机的文件放在/root 下面
  2. php protobuff 使用
  3. Unieap3.5错误收集
  4. 解码美国传奇网络券商:TradeStation
  5. load和ready
  6. javascript1
  7. XML的xPath格式
  8. Java面试10|数据库相关
  9. mac Path had bad ownership/permissions
  10. 自学Zabbix3.10.1.2-事件通知Notifications upon events-媒介类型SMS
  11. MVC和MTV模式
  12. static_assert与assert
  13. Window服务器 安装 Memcached
  14. Repeater 中TextBox 触发TextChanged事件
  15. Codeforces Beta Round #27 (Codeforces format, Div. 2)
  16. (拓扑)确定比赛名次 -- hdu -- 1285
  17. 30-hadoop-hbase-安装squirrel工具
  18. java高新技术
  19. Why ExerciseAlone May Not Be the Key to Weight Loss
  20. Java集合set的并、交、差操作

热门文章

  1. letsencrypt证书-管理工具certbot
  2. WebDriver--定位元素的8种方式
  3. 微信小程序如何性能测试?
  4. 怎样下载Firefox与Chrome浏览器驱动
  5. leetcode-汉明距离
  6. lintcode142 O(1)时间检测2的幂次
  7. 数据库Mysql的学习(六)-子查询和多表操作
  8. XX出行项目子系统-统计系统设计(定时器项目设计例子)
  9. ubuntu16.04图形界面安装中文输入法,中文展示
  10. scipy 图像处理-深度学习