【BZOJ3545&BZOJ3551】Peaks(kruskal重构树,主席树,dfs序)
题意:在Bytemountains有N座山峰,每座山峰有他的高度h_i。
有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,
现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。
N<=10^5, M,Q<=5*10^5,h_i,c,x<=10^9。
强制在线
思路:考虑按照最小生成树的过程,维护联通块能走到的所有权值的个数,可以用线段树合并
kruskal重构树是类似用kruskal计算最小生成树的过程,但每次合并两个点x,y时不是直接连边,而是新建一个点T,分别链接T和x,y,T的点权为(x,y)的边权
这样生成的树最多有2*n-1个点,而且有以下性质:
1.从某个点v出发,能走到的点一定在v向上走直到点权>u的点y,这个点u的子树中
2.是二叉树
3.按最小生成树生成是一个大根堆
4.任意两点路径上的最大值是lca的点权
预处理之后变成查询静态子树k大,dfs序+主席树即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef long double ld; 7 typedef pair<int,int> PII; 8 typedef pair<ll,int> Pli; 9 typedef pair<ll,ll> Pll; 10 typedef vector<int> VI; 11 typedef vector<PII> VII; 12 typedef pair<ll,ll>P; 13 #define N 200000+10 14 #define M 400000+10 15 #define INF 1e9 16 #define fi first 17 #define se second 18 #define MP make_pair 19 #define pb push_back 20 #define pi acos(-1) 21 #define mem(a,b) memset(a,b,sizeof(a)) 22 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 23 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 24 #define lowbit(x) x&(-x) 25 #define Rand (rand()*(1<<16)+rand()) 26 #define id(x) ((x)<=B?(x):m-n/(x)+1) 27 #define ls p<<1 28 #define rs p<<1|1 29 #define fors(i) for(auto i:e[x]) if(i!=p) 30 31 const int MOD=1e9+7,inv2=(MOD+1)/2; 32 //int p=1e6+3; 33 //double eps=1e-6; 34 int dx[4]={-1,1,0,0}; 35 int dy[4]={0,0,-1,1}; 36 37 struct edge 38 { 39 int x,y,z; 40 }a[500010]; 41 42 bool cmp(edge a,edge b) 43 { 44 return a.z<b.z; 45 } 46 47 struct node 48 { 49 int l,r,s; 50 }t[5000010]; 51 52 int f[N][17],g[N][17],head[N],vet[M],nxt[M],val[M],st[N],ed[N], 53 q[M],vis[N],fa[N],dep[N],h[N],d[N],root[M],bin[20],tot,n,m,Q,cnt,len,num; 54 55 56 int read() 57 { 58 int v=0,f=1; 59 char c=getchar(); 60 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 61 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 62 return v*f; 63 } 64 65 ll readll() 66 { 67 ll v=0,f=1; 68 char c=getchar(); 69 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 70 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 71 return v*f; 72 } 73 74 void add(int a,int b) 75 { 76 nxt[++tot]=head[a]; 77 vet[tot]=b; 78 head[a]=tot; 79 } 80 81 void dfs(int u) 82 { 83 vis[u]=1; q[++len]=u; 84 int e=head[u]; 85 while(e) 86 { 87 int v=vet[e]; 88 if(!vis[v]) 89 { 90 dep[v]=dep[u]+1; 91 f[v][0]=u; 92 g[v][0]=val[u]; 93 dfs(v); 94 } 95 e=nxt[e]; 96 } 97 if(u>n) q[++len]=u; 98 } 99 100 int dsu(int k) 101 { 102 if(fa[k]!=k) fa[k]=dsu(fa[k]); 103 return fa[k]; 104 } 105 106 int calc(int u,int x) 107 { 108 per(i,17,0) if(dep[u]>=bin[i]&&g[u][i]<=x) u=f[u][i]; 109 return u; 110 } 111 112 void update(int l,int r,int x,int p1,int &p2) 113 { 114 t[p2=++cnt]=t[p1]; 115 t[p2].s++; 116 if(l==r) return; 117 int mid=(l+r)>>1; 118 if(x<=mid) update(l,mid,x,t[p1].l,t[p2].l); 119 else update(mid+1,r,x,t[p1].r,t[p2].r); 120 } 121 122 int query(int l,int r,int k,int p1,int p2) 123 { 124 if(l==r) return l; 125 int mid=(l+r)>>1; 126 int tmp=t[t[p2].l].s-t[t[p1].l].s; 127 if(tmp>=k) return query(l,mid,k,t[p1].l,t[p2].l); 128 else return query(mid+1,r,k-tmp,t[p1].r,t[p2].r); 129 } 130 131 void build() 132 { 133 num=n; 134 sort(a+1,a+m+1,cmp); 135 tot=0; 136 rep(i,1,m) 137 { 138 int p=dsu(a[i].x),q=dsu(a[i].y); 139 if(p!=q) 140 { 141 num++; 142 fa[p]=fa[q]=num; 143 val[num]=a[i].z; 144 add(num,q); 145 add(num,p); 146 if(num==2*n-1) break; 147 } 148 } 149 len=0; 150 rep(i,1,n) 151 if(!vis[i]) dfs(dsu(i)); 152 rep(i,1,16) 153 rep(j,1,num) 154 if(dep[j]>=bin[i]) 155 { 156 f[j][i]=f[f[j][i-1]][i-1]; 157 g[j][i]=max(g[j][i-1],g[f[j][i-1]][i-1]); 158 } 159 cnt=0; 160 rep(i,1,len) 161 { 162 int u=q[i]; 163 if(u<=n) update(1,n,h[u],root[i-1],root[i]); 164 else 165 { 166 root[i]=root[i-1]; 167 if(!st[u]) st[u]=i; 168 else ed[u]=i; 169 } 170 } 171 } 172 173 void solve() 174 { 175 int v,x,k; 176 int lastans=0; 177 rep(i,1,Q) 178 { 179 v=read(),x=read(),k=read(); 180 if(lastans!=-1) v^=lastans,x^=lastans,k^=lastans; 181 int u=calc(v,x); 182 int L=root[st[u]],R=root[ed[u]]; 183 if(t[R].s-t[L].s<k) lastans=-1; 184 else lastans=d[query(1,n,t[R].s-t[L].s-k+1,L,R)]; 185 printf("%d\n",lastans); 186 } 187 } 188 189 int main() 190 { 191 bin[0]=1; 192 rep(i,1,19) bin[i]=bin[i-1]<<1; 193 n=read(),m=read(),Q=read(); 194 rep(i,1,n) h[i]=read(),d[i]=h[i]; 195 sort(d+1,d+n+1); 196 rep(i,1,n) h[i]=lower_bound(d+1,d+n+1,h[i])-d; 197 rep(i,1,2*n) fa[i]=i; 198 rep(i,1,m) 199 { 200 a[i].x=read(); 201 a[i].y=read(); 202 a[i].z=read(); 203 } 204 build(); 205 solve(); 206 return 0; 207 }
null