[BZOJ]4336: BJOI2015 骑士的旅行 树链剖分+STL(multiset)
2017-10-19 22:11
274 查看
Description
在一片古老的土地上,有一个繁荣的文明。
这片大地几乎被森林覆盖,有N座城坐落其中。巧合的是,这N座城由恰好N-1条双向道路连接起来,使得任意两座城都是连通的。也就是说,这些城形成了树的结构,任意两座城之间有且仅有一条简单路径。在这个文明中,骑士是尤其受到尊崇的职业。任何一名骑士,都是其家族乃至家乡的荣耀。Henry从小就渴望成为一名能守护家乡、驱逐敌人的骑士。勤奋训练许多年后,Henry终于满18岁了。他决定离开家乡,向那些成名已久的骑士们发起挑战!根据Henry的调查,大陆上一共有M名受封骑士,不妨编号为1到M。第i个骑士居住在城Pi,武力值为Fi。Henry计划进行若干次旅行,每次从某座城出发沿着唯一的简单路径前往另一座城,同时会挑战路线上武力值最高的K个骑士(Henry的体力有限,为了提高水平,当然要挑战最强的骑士)。如果路线上的骑士不足K人,Henry会挑战遇到的所有人。每次旅行前,可能会有某些骑士的武力值或定居地发生变化,Henry自然会打听消息,并对计划做出调整。
为了在每次旅行时做好充分准备,Henry希望你能帮忙在每次旅行前计算出这条路线上他将挑战哪些对手。
在一片古老的土地上,有一个繁荣的文明。
这片大地几乎被森林覆盖,有N座城坐落其中。巧合的是,这N座城由恰好N-1条双向道路连接起来,使得任意两座城都是连通的。也就是说,这些城形成了树的结构,任意两座城之间有且仅有一条简单路径。在这个文明中,骑士是尤其受到尊崇的职业。任何一名骑士,都是其家族乃至家乡的荣耀。Henry从小就渴望成为一名能守护家乡、驱逐敌人的骑士。勤奋训练许多年后,Henry终于满18岁了。他决定离开家乡,向那些成名已久的骑士们发起挑战!根据Henry的调查,大陆上一共有M名受封骑士,不妨编号为1到M。第i个骑士居住在城Pi,武力值为Fi。Henry计划进行若干次旅行,每次从某座城出发沿着唯一的简单路径前往另一座城,同时会挑战路线上武力值最高的K个骑士(Henry的体力有限,为了提高水平,当然要挑战最强的骑士)。如果路线上的骑士不足K人,Henry会挑战遇到的所有人。每次旅行前,可能会有某些骑士的武力值或定居地发生变化,Henry自然会打听消息,并对计划做出调整。
为了在每次旅行时做好充分准备,Henry希望你能帮忙在每次旅行前计算出这条路线上他将挑战哪些对手。
题解:
%%%zyf2000,因为k很小,所以可以每个叶子结点开一个multiset,存这个结点有哪些骑士,同时对线段树每个结点建一个结构体,存当前这一段有哪些骑士,然后儿子更新父亲的时候就用归并排序那样合并就行了,其它没什么要注意的了。代码也不难写。代码:
#include<bits/stdc++.h> using namespace std; #define LL long long const int Maxn=40010; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} return x*f; } multiset<int>S[Maxn<<1]; int n,m,q,k,F[Maxn],P[Maxn];//F武力值 P居住地 struct A{int Len,b[22];}a[Maxn<<1]; struct Tree{int l,r,lc,rc;}tr[Maxn<<1]; int top[Maxn],tot[Maxn],dep[Maxn],son[Maxn],ys[Maxn],z=0,fa[Maxn]; struct Edge{int y,next;}e[Maxn<<1]; int last[Maxn],len=0; void ins(int x,int y){int t=++len;e[t].y=y;e[t].next=last[x];last[x]=t;} void dfs1(int x,int f) { fa[x]=f;dep[x]=dep[f]+1;tot[x]=1; for(int i=last[x];i;i=e[i].next) { int y=e[i].y; if(y!=f) { dfs1(y,x); if(tot[y]>tot[son[x]])son[x]=y; tot[x]+=tot[y]; } } } void dfs2(int x,int Top) { top[x]=Top;ys[x]=++z; if(son[x])dfs2(son[x],Top); for(int i=last[x];i;i=e[i].next) { int y=e[i].y; if(y!=fa[x]&&y!=son[x])dfs2(y,y); } } int trlen=0; void build(int l,int r) { int t=++trlen; tr[t].l=l;tr[t].r=r; if(l<r) { int mid=l+r>>1; tr[t].lc=trlen+1;build(l,mid); tr[t].rc=trlen+1;build(mid+1,r); } } A merge(A x,A y)//归并 { int l1=1,l2=1;A re;re.Len=0; while(l1<=x.Len&&l2<=y.Len&&re.Len<k) { if(x.b[l1]>y.b[l2])re.b[++re.Len]=x.b[l1++]; else re.b[++re.Len]=y.b[l2++]; } while(l1<=x.Len&&re.Len<k)re.b[++re.Len]=x.b[l1++]; while(l2<=y.Len&&re.Len<k)re.b[++re.Len]=y.b[l2++]; return re; } int pos; void change(int now,int p,int x,int o) { if(tr[now].l==tr[now].r) { multiset<int>::iterator t; if(o==1)S[pos].insert(x); else S[pos].erase(S[pos].find(x)); a[now].Len=0; if(!S[pos].empty()) { t=S[pos].end();t--; while(a[now].Len<k) { a[now].b[++a[now].Len]=*t; if(t==S[pos].begin())break; t--; } } return; } int lc=tr[now].lc,rc=tr[now].rc,mid=tr[now].l+tr[now].r>>1; if(p<=mid)change(lc,p,x,o);else change(rc,p,x,o); a[now]=merge(a[lc],a[rc]); } A query(int now,int l,int r) { if(tr[now].l==l&&tr[now].r==r)return a[now]; int lc=tr[now].lc,rc=tr[now].rc,mid=tr[now].l+tr[now].r>>1; if(r<=mid)return query(lc,l,r); else if(l>mid)return query(rc,l,r); else { A re=merge(query(lc,l,mid),query(rc,mid+1,r)); return re; } } void solve(int x,int y) { int tx=top[x],ty=top[y];A ans;ans.Len=0; while(tx!=ty) { if(dep[tx]<dep[ty])swap(tx,ty),swap(x,y); ans=merge(ans,query(1,ys[tx],ys[x])); x=fa[tx];tx=top[x]; } if(dep[x]>dep[y])swap(x,y); ans=merge(ans,query(1,ys[x],ys[y])); if(!ans.Len){puts("-1");return;} for(int i=1;i<=ans.Len;i++)printf("%d ",ans.b[i]);puts(""); } int main() { n=read(); for(int i=1;i<n;i++){int x=read(),y=read();ins(x,y);ins(y,x);} dep[0]=0;dfs1(1,0);dfs2(1,1);build(1,z); m=read(); for(int i=1;i<=m;i++)F[i]=read(),P[i]=read(); q=read();k=read(); for(int i=1;i<=m;i++)pos=P[i],change(1,ys[P[i]],F[i],1); while(q--) { int op=read(),x=read(),y=read(); if(op==1)solve(x,y); else if(op==2)pos=P[x],change(1,ys[P[x]],F[x],-1),P[x]=y,pos=P[x],change(1,ys[P[x]],F[x],1); else pos=P[x],change(1,ys[P[x]],F[x],-1),F[x]=y,pos=P[x],change(1,ys[P[x]],F[x],1); } }
相关文章推荐
- 2017.10.6 BJOI2015 bzoj4336 骑士的旅行
- [BZOJ4336][BJOI2015]骑士的旅行(树链剖分+线段树+multiset+归并)
- BZOJ 4336 BJOI2015 骑士的旅行
- 4336: BJOI2015 骑士的旅行
- bzoj4336: BJOI2015 骑士的旅行
- 【Bzoj4336】骑士的旅行
- bzoj4336: BJOI2015 骑士的旅行
- BZOJ 4337: BJOI2015 树的同构
- bzoj 4337: BJOI2015 树的同构 (树hash)
- [树hash]BZOJ 4337——BJOI2015 树的同构
- 【BZOJ】4337 BJOI2015 树的同构 树hash
- 【Hash】bzoj4337 BJOI2015树的同构
- BZOJ 4338 BJOI2015 糖果
- BZOJ 4337: BJOI2015 树的同构 树hash
- 2017.10.6 BJOI2015 bzoj4337 树的同构
- BZOJ 4337 BJOI2015 树的同构 Hash
- BZOJ 4337: BJOI2015 树的同构|Hash
- 【BZOJ4337】BJOI2015 树的同构 括号序列
- [BZOJ4337][BJOI2015]树的同构(树的最小表示法)
- bzoj 4337: BJOI2015 树的同构 树哈希