[BZOJ4336][BJOI2015]骑士的旅行(树链剖分+线段树)
树链剖分,对每个叶子用multiset记录前K大士兵,其余节点通过从儿子归并维护前K大士兵。过于模板。
1 #include<set> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #define ls (x<<1) 6 #define rs (ls|1) 7 #define lson ls,L,mid 8 #define rson rs,mid+1,R 9 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 10 #define For(i,x) for (int i=h[x],k; i; i=nxt[i]) 11 using namespace std; 12 13 const int N=40010; 14 int n,m,u,v,op,x,y,Q,K,cnt,tim,dfn[N],son[N],sz[N],dep[N],fa[N],top[N],h[N],to[N<<1],nxt[N<<1]; 15 struct P{ int x,k; }p[N]; 16 struct Se{ 17 int tot,a[30]; 18 Se(){ tot=0; memset(a,0,sizeof(a)); } 19 Se(const Se &b){ tot=b.tot; memcpy(a,b.a,sizeof(a)); } 20 }T[N<<2]; 21 multiset<int>S[N<<2]; 22 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; } 23 24 void dfs(int x){ 25 sz[x]=1; dep[x]=dep[fa[x]]+1; 26 For(i,x) if ((k=to[i])!=fa[x]){ 27 fa[k]=x; dfs(k); sz[x]+=sz[k]; 28 if (sz[k]>sz[son[x]]) son[x]=k; 29 } 30 } 31 32 void dfs2(int x,int tp){ 33 dfn[x]=++tim; top[x]=tp; 34 if (son[x]) dfs2(son[x],tp); 35 For(i,x) if ((k=to[i])!=fa[x] && k!=son[x]) dfs2(k,k); 36 } 37 38 Se merge(Se a,Se b){ 39 Se res; 40 for (int i=1,j=1; i<=a.tot || j<=b.tot; ){ 41 if ((i<=a.tot) && (j>b.tot || b.a[j]<a.a[i])) res.a[++res.tot]=a.a[i++]; else res.a[++res.tot]=b.a[j++]; 42 if (res.tot==K) break; 43 } 44 return res; 45 } 46 47 void mdf(int x,int L,int R,int pos,int k,int op){ 48 if (L==R){ 49 if (!op) S[x].erase(S[x].find(k)); else S[x].insert(k); 50 T[x].tot=0; multiset<int>::iterator it=S[x].end(); 51 while (1){ 52 if (it==S[x].begin()) break; it--; 53 T[x].a[++T[x].tot]=*it; 54 if (T[x].tot==K) break; 55 } 56 return; 57 } 58 int mid=(L+R)>>1; 59 if (pos<=mid) mdf(lson,pos,k,op); else mdf(rson,pos,k,op); 60 T[x]=merge(T[ls],T[rs]); 61 } 62 63 Se que(int x,int L,int R,int l,int r){ 64 if (L==l && r==R) return T[x]; 65 int mid=(L+R)>>1; 66 if (r<=mid) return que(lson,l,r); 67 else if (l>mid) return que(rson,l,r); 68 else return merge(que(lson,l,mid),que(rson,mid+1,r)); 69 } 70 71 void solve(int x,int y){ 72 Se res; 73 for (; top[x]!=top[y]; x=fa[top[x]]){ 74 if (dep[top[x]]<dep[top[y]]) swap(x,y); 75 res=merge(res,que(1,1,n,dfn[top[x]],dfn[x])); 76 } 77 if (dep[x]<dep[y]) swap(x,y); 78 res=merge(res,que(1,1,n,dfn[y],dfn[x])); 79 if (!res.tot) puts("-1"); 80 else{ rep(i,1,res.tot) printf("%d ",res.a[i]); puts(""); } 81 } 82 83 int main(){ 84 freopen("bzoj4336.in","r",stdin); 85 freopen("bzoj4336.out","w",stdout); 86 scanf("%d",&n); 87 rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u); 88 dfs(1); dfs2(1,1); 89 scanf("%d",&m); 90 rep(i,1,m) scanf("%d%d",&p[i].k,&p[i].x); 91 scanf("%d%d",&Q,&K); 92 rep(i,1,m) mdf(1,1,n,dfn[p[i].x],p[i].k,1); 93 while (Q--){ 94 scanf("%d%d%d",&op,&x,&y); 95 if (op==1) solve(x,y); 96 if (op==2) mdf(1,1,n,dfn[p[x].x],p[x].k,0),p[x].x=y,mdf(1,1,n,dfn[p[x].x],p[x].k,1); 97 if (op==3) mdf(1,1,n,dfn[p[x].x],p[x].k,0),p[x].k=y,mdf(1,1,n,dfn[p[x].x],p[x].k,1); 98 } 99 return 0; 100 }