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

然后发现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. java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application-dev.yml'

    如果你的项目没有配置错误,配置文件名称也正常,还出现这个问题,那一定是你的yml文件编码的问题 先附上一张项目架构图 当我启动服务器寻找配置文件的时候,服务器提示这样的错误信息 java.lang.I ...

  2. POJ1845

    这还是一道综合了许多数论的知识点的,做完也涨了不少姿势 但还是因为约数和公式这个鬼东西去找了度娘 题意很简单,就是求\(A^B\)的约数之和\(mod\ 9901\). 但是这种题意越是简单的题目越是 ...

  3. CentOS搭建NAT和DHCP服务,实现共享上网

    什么是NAT? NAT(Network address translation)即网络地址转换,作为一种过渡解决手段,可以用来减少对全球合法IP地址的需求.简单的说,NAT就是在内部专用网络中使用内部 ...

  4. default construction

    4种情况下编译器会构造出nontrivial(有用)的构造函数 带有default construction的member class object 我们有两个class: class Foo { p ...

  5. HTML5-indexedDB使用常见错误总结

    indexedDB使用过程中常常会出现以下错误: Failed to execute ‘createObjectStore’ on ‘IDBDatabase’: The database is not ...

  6. C#【结对编程作业】小学数学习题助手

    一.软件成品展示 软件本体下载(包括程序及其更新日志,源码工程包,UML图,API接口文档,算法介绍文档,算式计算excel实例,浅查重程序) 链接: http://pan.baidu.com/s/1 ...

  7. 【实践报告】Linux实践四

    Linux内核分析 实践四——ELF文件格式分析 一.概述 1.ELF全称Executable and Linkable Format,可执行连接格式,ELF格式的文件用于存储Linux程序.ELF文 ...

  8. 《Linux内核分析》第八周学习笔记

    <Linux内核分析>第八周学习笔记 进程的切换和系统的一般执行过程 郭垚 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163 ...

  9. Java Swing 实现系统托盘图标

    在实现托盘图标时,出现弹出式菜单显示中文乱码,无法显示正确的文字 查询相关资料后发现是字符编码不匹配,查询资料出处 解决方法 1.通过修改Java项目的默认编码为GBK: 2.在Run Configu ...

  10. NodeJS 学习记录

    这里是我学习NodeJs的学习记录 URL:网址解析的好帮手 URL,URI 首先,URI是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源.而URL是u ...