首先大概有一个树剖+树套树的做法,但我哪会写啊

然后发现k很小,如果用线段树记每个区间前k大的的话,可以O(k)地合并

而且一个点还有可能有好多个骑士,所以要用multiset维护一下

然后树剖就好啦

 #include<bits/stdc++.h>
#define pa pair<int,int>
#define CLR(a,x) memset(a,x,sizeof(a))
#define IT multiset<int>::iterator
using namespace std;
typedef long long ll;
const int maxn=4e4+,maxk=; inline ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int eg[maxn*][],egh[maxn],ect,smr[maxn][];
int N,M,Q,K;
int wson[maxn],dfn[maxn],dep[maxn],siz[maxn],top[maxn],fa[maxn],tot;
int fr[maxn*][maxk],id[maxn],ans[maxk],tmp[maxk];
multiset<int,greater<int> > st[maxn]; inline void adeg(int a,int b){
eg[++ect][]=b;eg[ect][]=egh[a];egh[a]=ect;
} void dfs1(int x){
siz[x]=;int mm=;
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];
if(b==fa[x]) continue;
fa[b]=x;dep[b]=dep[x]+;
dfs1(b);siz[x]+=siz[b];
if(siz[b]>mm) mm=siz[b],wson[x]=b;
}
}
void dfs2(int x){
dfn[x]=++tot;id[tot]=x;
top[x]=(x==wson[fa[x]]?top[fa[x]]:x);
if(wson[x]) dfs2(wson[x]);
for(int i=egh[x];i;i=eg[i][]){
int b=eg[i][];
if(b==wson[x]||b==fa[x]) continue;
dfs2(b);
}
} inline void update(int p){
int l=p<<,r=p<<|;
int a=,b=,i=;
for(;a<=fr[l][]&&i<K;a++){
for(;b<=fr[r][]&&fr[r][b]>fr[l][a]&&i<K;b++)
fr[p][++i]=fr[r][b];
if(i<K) fr[p][++i]=fr[l][a];
}for(;b<=fr[r][]&&i<K;b++) fr[p][++i]=fr[r][b];
fr[p][]=i;
} void build(int p,int l,int r){
if(l==r){
int i=;
for(IT it=st[id[l]].begin();i<K&&it!=st[id[l]].end();it++){
fr[p][++i]=*it;
}fr[p][]=i;
}else{
int m=l+r>>;
build(p<<,l,m);build(p<<|,m+,r);
update(p);
}
} void query(int p,int l,int r,int x,int y){
if(x<=l&&r<=y){
if(!ans[]){
memcpy(ans,fr[p],sizeof(ans));
return;
}
int a=,b=,i=;
for(;a<=fr[p][]&&i<K;a++){
for(;b<=ans[]&&ans[b]>fr[p][a]&&i<K;b++)
tmp[++i]=ans[b];
if(i<K) tmp[++i]=fr[p][a];
}for(;b<=ans[]&&i<K;b++) tmp[++i]=ans[b];
tmp[]=i;
memcpy(ans,tmp,sizeof(ans));
}else{
int m=l+r>>;
if(x<=m) query(p<<,l,m,x,y);
if(y>=m+) query(p<<|,m+,r,x,y);
}
} void change(int p,int l,int r,int x,int y,bool b){
if(l==r){
if(!b) st[id[l]].erase(st[id[l]].find(y));
else st[id[l]].insert(y);
int i=;
for(IT it=st[id[l]].begin();i<K&&it!=st[id[l]].end();it++){
fr[p][++i]=*it;
}fr[p][]=i;
}else{
int m=l+r>>;
if(x<=m) change(p<<,l,m,x,y,b);
else change(p<<|,m+,r,x,y,b);
update(p);
}
} void solve1(int x,int y){
ans[]=,tmp[]=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
query(,,N,dfn[top[x]],dfn[x]);
// printf("%d %d\n",dfn[top[x]],x);
x=fa[top[x]];
}
if(dep[x]<dep[y]) swap(x,y);
query(,,N,dfn[y],dfn[x]);
} void solve2(int x,int y){
change(,,N,dfn[smr[x][]],smr[x][],);
change(,,N,dfn[y],smr[x][],);
smr[x][]=y;
}
void solve3(int x,int y){
change(,,N,dfn[smr[x][]],smr[x][],);
change(,,N,dfn[smr[x][]],y,);
smr[x][]=y;
} int main(){
//freopen("","r",stdin);
int i,j,k;
N=rd();
for(i=;i<N;i++){
int a=rd(),b=rd();
adeg(a,b);adeg(b,a);
}
M=rd();
for(i=;i<=M;i++){
smr[i][]=rd(),smr[i][]=rd();
st[smr[i][]].insert(smr[i][]);
}
Q=rd(),K=rd();
dep[]=;dfs1();
dfs2();build(,,N);
for(j=;j<=Q;j++){
int a=rd(),b=rd(),c=rd();
if(a==){
solve1(b,c);
if(ans[]==) printf("-1");
for(i=;i<=ans[];i++)
printf("%d ",ans[i]);
printf("\n");
}else if(a==) solve2(b,c);
else solve3(b,c);
}
return ;
}

bzoj4336 骑士的旅行 (树链剖分+multiset)的更多相关文章

  1. [BZOj4336][BJOI2015]骑士的旅行(树链剖分+线段树)

    树链剖分,对每个叶子用multiset记录前K大士兵,其余节点通过从儿子归并维护前K大士兵.过于模板. #include<set> #include<cstdio> #incl ...

  2. CF487E Tourists(圆方树+树链剖分+multiset/可删堆)

    CF487E Tourists(圆方树+树链剖分+multiset/可删堆) Luogu 给出一个带点权的无向图,两种操作: 1.修改某点点权. 2.询问x到y之间简单路径能走过的点的最小点权. 题解 ...

  3. BZOJ 3531: [Sdoi2014]旅行 [树链剖分]

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1685  Solved: 751[Submit][Status] ...

  4. BZOJ3531:[SDOI2014]旅行(树链剖分)

    Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰 ...

  5. P3313 [SDOI2014]旅行——树链剖分+线段树(动态开点?)

    P3313 [SDOI2014]旅行 一棵树,其中的点分类,点有权值,在一条链上找到一类点中的最大值或总和: 树链剖分把树变成链: 把每个宗教单开一个线段树,维护区间总和和最大值: 宗教很多,需要动态 ...

  6. BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树

    题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...

  7. cogs 186. [USACO Oct08] 牧场旅行 树链剖分 LCA

    186. [USACO Oct08] 牧场旅行 ★★☆   输入文件:pwalk.in   输出文件:pwalk.out   逐字节对比时间限制:1 s   内存限制:128 MB n个被自然地编号为 ...

  8. 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)

    题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...

  9. BZOJ 2157 旅行(树链剖分码农题)

    写了5KB,1发AC... 题意:给出一颗树,支持5种操作. 1.修改某条边的权值.2.将u到v的经过的边的权值取负.3.求u到v的经过的边的权值总和.4.求u到v的经过的边的权值最大值.5.求u到v ...

随机推荐

  1. HDU 1109 Run Away

    题目大意:给一个矩阵的长宽,再给n个点,求矩阵区域内某个点到各个点的最小距离的最大值,输出所求点的坐标 这道题我还是写了随机化乱搞,不过由于比较懒于是就没有写模拟退火,不过也是可以AC的 我们先初始随 ...

  2. 51Nod 1443 路径和树

    还是一道很简单的基础题,就是一个最短路径树的类型题目 我们首先可以发现这棵树必定满足从1出发到其它点的距离都是原图中的最短路 换句话说,这棵树上的每一条边都是原图从1出发到其它点的最短路上的边 那么直 ...

  3. [Spark][Python]Spark Python 索引页

    Spark Python 索引页 为了查找方便,建立此页 === RDD 基本操作: [Spark][Python]groupByKey例子

  4. *C#(WPF)--矩阵拖动和矩阵动画(拖动展开,不足动画效果)

    最近在研发新的项目,遇到了一个桌面模式下的难点--展开动画.之前动画这方面没做过,也许很多人开始做的时候也会遇到相关问题,因此我把几个重点及实际效果图总结展示出来: 我的开发环境是在VS2017下进行 ...

  5. RabbitMQ 优先级队列-为队列赋权

    RabbitMQ 消息收发是按顺序收发,一般情况下是先收到的消息先处理,即可以实现先进先出的消息处理.但如果消息者宕机或其他原因,导致消息接收以后,未确认,那么消息会重新Requeue到队列中,就打破 ...

  6. host大法之GitHub上不去

    dns解析慢,github上不去,慢 修改host. windows下路径为:C:\Windows\System32\drivers\etc\hosts Linux下路径:/etc/hosts 加入: ...

  7. mysql操作命令梳理(5)-执行sql语句查询即mysql状态说明

    在日常mysql运维中,经常要查询当前mysql下正在执行的sql语句及其他在跑的mysql相关线程,这就用到mysql processlist这个命令了.mysql> show process ...

  8. sublime text3 安装package control 出现问题解决过程记录

    1.安装package control 失败 通过最简单的自动安装 package control 失败(详见package control官网). 报错展示: File "./python ...

  9. ACM-ICPC 2018 沈阳赛区网络预赛 G. Spare Tire

    这题很好啊,好在我没做出来...大概分析了一下,题目大概意思就是求 问所有满足1<=i<=n且i与m互素的ai之和 最开始我们队的做法是类似线性筛的方法去筛所有数,把数筛出来后剩下数即可, ...

  10. 网易云课堂-----Linux内核分析-----期末主观题

    姚歌 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 下面是对8个课题的 ...