bzoj4336 骑士的旅行 (树链剖分+multiset)
首先大概有一个树剖+树套树的做法,但我哪会写啊
然后发现k很小,如果用线段树记每个区间前k大的的话,可以O(k)地合并
而且一个点还有可能有好多个骑士,所以要用multiset维护一下
然后树剖就好啦
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 #define IT multiset<int>::iterator 5 using namespace std; 6 typedef long long ll; 7 const int maxn=4e4+10,maxk=25; 8 9 inline ll rd(){ 10 ll x=0;char c=getchar();int neg=1; 11 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 12 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 13 return x*neg; 14 } 15 16 int eg[maxn*2][2],egh[maxn],ect,smr[maxn][2]; 17 int N,M,Q,K; 18 int wson[maxn],dfn[maxn],dep[maxn],siz[maxn],top[maxn],fa[maxn],tot; 19 int fr[maxn*4][maxk],id[maxn],ans[maxk],tmp[maxk]; 20 multiset<int,greater<int> > st[maxn]; 21 22 inline void adeg(int a,int b){ 23 eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect; 24 } 25 26 void dfs1(int x){ 27 siz[x]=1;int mm=0; 28 for(int i=egh[x];i;i=eg[i][1]){ 29 int b=eg[i][0]; 30 if(b==fa[x]) continue; 31 fa[b]=x;dep[b]=dep[x]+1; 32 dfs1(b);siz[x]+=siz[b]; 33 if(siz[b]>mm) mm=siz[b],wson[x]=b; 34 } 35 } 36 void dfs2(int x){ 37 dfn[x]=++tot;id[tot]=x; 38 top[x]=(x==wson[fa[x]]?top[fa[x]]:x); 39 if(wson[x]) dfs2(wson[x]); 40 for(int i=egh[x];i;i=eg[i][1]){ 41 int b=eg[i][0]; 42 if(b==wson[x]||b==fa[x]) continue; 43 dfs2(b); 44 } 45 } 46 47 inline void update(int p){ 48 int l=p<<1,r=p<<1|1; 49 int a=1,b=1,i=0; 50 for(;a<=fr[l][0]&&i<K;a++){ 51 for(;b<=fr[r][0]&&fr[r][b]>fr[l][a]&&i<K;b++) 52 fr[p][++i]=fr[r][b]; 53 if(i<K) fr[p][++i]=fr[l][a]; 54 }for(;b<=fr[r][0]&&i<K;b++) fr[p][++i]=fr[r][b]; 55 fr[p][0]=i; 56 } 57 58 void build(int p,int l,int r){ 59 if(l==r){ 60 int i=0; 61 for(IT it=st[id[l]].begin();i<K&&it!=st[id[l]].end();it++){ 62 fr[p][++i]=*it; 63 }fr[p][0]=i; 64 }else{ 65 int m=l+r>>1; 66 build(p<<1,l,m);build(p<<1|1,m+1,r); 67 update(p); 68 } 69 } 70 71 void query(int p,int l,int r,int x,int y){ 72 if(x<=l&&r<=y){ 73 if(!ans[0]){ 74 memcpy(ans,fr[p],sizeof(ans)); 75 return; 76 } 77 int a=1,b=1,i=0; 78 for(;a<=fr[p][0]&&i<K;a++){ 79 for(;b<=ans[0]&&ans[b]>fr[p][a]&&i<K;b++) 80 tmp[++i]=ans[b]; 81 if(i<K) tmp[++i]=fr[p][a]; 82 }for(;b<=ans[0]&&i<K;b++) tmp[++i]=ans[b]; 83 tmp[0]=i; 84 memcpy(ans,tmp,sizeof(ans)); 85 }else{ 86 int m=l+r>>1; 87 if(x<=m) query(p<<1,l,m,x,y); 88 if(y>=m+1) query(p<<1|1,m+1,r,x,y); 89 } 90 } 91 92 void change(int p,int l,int r,int x,int y,bool b){ 93 if(l==r){ 94 if(!b) st[id[l]].erase(st[id[l]].find(y)); 95 else st[id[l]].insert(y); 96 int i=0; 97 for(IT it=st[id[l]].begin();i<K&&it!=st[id[l]].end();it++){ 98 fr[p][++i]=*it; 99 }fr[p][0]=i; 100 }else{ 101 int m=l+r>>1; 102 if(x<=m) change(p<<1,l,m,x,y,b); 103 else change(p<<1|1,m+1,r,x,y,b); 104 update(p); 105 } 106 } 107 108 void solve1(int x,int y){ 109 ans[0]=0,tmp[0]=0; 110 while(top[x]!=top[y]){ 111 if(dep[top[x]]<dep[top[y]]) swap(x,y); 112 query(1,1,N,dfn[top[x]],dfn[x]); 113 // printf("%d %d\n",dfn[top[x]],x); 114 x=fa[top[x]]; 115 } 116 if(dep[x]<dep[y]) swap(x,y); 117 query(1,1,N,dfn[y],dfn[x]); 118 } 119 120 void solve2(int x,int y){ 121 change(1,1,N,dfn[smr[x][1]],smr[x][0],0); 122 change(1,1,N,dfn[y],smr[x][0],1); 123 smr[x][1]=y; 124 } 125 void solve3(int x,int y){ 126 change(1,1,N,dfn[smr[x][1]],smr[x][0],0); 127 change(1,1,N,dfn[smr[x][1]],y,1); 128 smr[x][0]=y; 129 } 130 131 int main(){ 132 //freopen("","r",stdin); 133 int i,j,k; 134 N=rd(); 135 for(i=1;i<N;i++){ 136 int a=rd(),b=rd(); 137 adeg(a,b);adeg(b,a); 138 } 139 M=rd(); 140 for(i=1;i<=M;i++){ 141 smr[i][0]=rd(),smr[i][1]=rd(); 142 st[smr[i][1]].insert(smr[i][0]); 143 } 144 Q=rd(),K=rd(); 145 dep[1]=1;dfs1(1); 146 dfs2(1);build(1,1,N); 147 for(j=1;j<=Q;j++){ 148 int a=rd(),b=rd(),c=rd(); 149 if(a==1){ 150 solve1(b,c); 151 if(ans[0]==0) printf("-1"); 152 for(i=1;i<=ans[0];i++) 153 printf("%d ",ans[i]); 154 printf("\n"); 155 }else if(a==2) solve2(b,c); 156 else solve3(b,c); 157 } 158 return 0; 159 }