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

然后发现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. 如何使用串口来给STM32下载程序

    前言 第一次学习STM32的时候,不知道有调试器这个东西,所以一直是通过串口来给STM32下载程序,下载速度也还算可以,一般是几秒钟完成.后来用了调试器,可以直接在Keil环境下进行下载,而且还可以进 ...

  2. linux下expect环境安装以及简单脚本测试

    expect是交互性很强的脚本语言,可以帮助运维人员实现批量管理成千上百台服务器操作,是一款很实用的批量部署工具!expect依赖于tcl,而linux系统里一般不自带安装tcl,所以需要手动安装 下 ...

  3. Note: SE Class's Individual Project

    虽然第一个Project还有点小问题需要修改,但是大体已经差不多了,先把blog记在这里,算是开博第一篇吧! 1.项目预计的用时 本来看到这个题的时候想的并不多,但是看了老师的要求才觉得如此麻烦ORZ ...

  4. Mooc总结——Linux内核分析

    朱荟潼+ 原创作品转载请注明出处 :<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 学习笔记链接汇总 第 ...

  5. WinForm(WPF) splash screen demo with C#

    https://www.codeproject.com/Articles/21062/Splash-Screen-Control https://www.codeproject.com/Article ...

  6. Mybatis复杂嵌套关联一例

    Mybatis  three entity relation:association in collection PatentMapper.xml <resultMap id="Bas ...

  7. jquery judge element exist

    http://learn.jquery.com/using-jquery-core/faq/how-do-i-test-whether-an-element-exists/ if ( $( " ...

  8. Selenium自动化测试框架

    如下图所示,为公司搭建的基于Selenium+Ant+TestNG+Jenkins的持续集成的自动化测试框架. Selenium: Page Object Model+Data Driver(Exce ...

  9. Jquery ajax 表单.serialize() 和serializeArray()序列化$.param()

    .serialize() 方法创建以标准 URL 编码表示的文本字符串.它的操作对象是代表表单元素集合的 jQuery 对象. 表单元素有几种类型: <form> <div>& ...

  10. 如何根据元素的className获取元素?

    getElementsByClassName()是HTML5 新增的DOM API.IE8以下不支持 我们知道,原生的方法,是getElementById()和getElementsByTagName ...