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 }

 

posted @ 2018-10-15 21:03  Ressed  阅读(233)  评论(0编辑  收藏  举报