BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
2017-03-26 19:09
495 查看
3551: [ONTAK2010]Peaks加强版
题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线PoPoQQQ大爷题解传送门
说一下感受:
容易发现一定选最小生成树上的边,然后用到了一个神奇的东西
Kruskal重构树
进行Kruskal过程中,每条边用一个点代替,左右儿子分别是连的两个点的当前的父亲这样就形成了一棵树,叶子都是原图上的点,其他都是原图上的边
深度越小的点对应的边权值越大
两点路径上的权值不变
这样的话,与一个点通过权值\(\le lim\)的边连通,就是这个点权值\(\le lim\)的父亲对应的子树中的点
对dfs序建主席树就行了
实现上我只将原图中的点加入了dfs序
该死离散化写错了WA了半小时
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; #define lc(x) t[x].l #define rc(x) t[x].r const int N=2e5+5, M=5e5+5; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n, m, Q, val , tot, u, lim, k, mp ; struct meow{ int u,v,w; bool operator <(const meow &r) const{return w<r.w;} }a[M]; namespace ufs{ int fa ; int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);} } struct edge{int v,ne;}e[N<<1]; int cnt, h ; inline void ins(int u, int v) { e[++cnt]=(edge){v, h[u]}; h[u]=cnt; } void Kruskal() { using ufs::fa; using ufs::find; sort(a+1, a+1+m); int cnt=0; for(int i=1; i<=m; i++) { int u=a[i].u, v=a[i].v, w=a[i].w; int x=find(u), y=find(v); if(x==y) continue; val[++tot]=w; //printf("hey %d %d %d %d\n",x,y,tot,val[tot]); ins(tot, x); ins(tot, y); fa[x]=fa[y]=fa[tot]=tot; if(++cnt == n-1) break; } } int deep , dfc, ver , L , R ; int fa [20]; void dfs(int u) { //printf("dfs %d %d\n",u,val[u]); if(u<=n) ver[++dfc]=u; L[u]=dfc; for(int i=1; (1<<i)<=deep[u]; i++) fa[u][i] = fa[ fa[u][i-1] ][i-1]; for(int i=h[u];i;i=e[i].ne) if(e[i].v != fa[u][0]) { fa[e[i].v][0]=u; deep[e[i].v]=deep[u]+1; dfs(e[i].v); } R[u]=dfc; } struct ChairTree{ struct meow{int l,r,size;}t[N*30]; int sz, root ; void insert(int &x, int l, int r, int p) { t[++sz]=t[x]; x=sz; t[x].size++; if(l==r) return; int mid=(l+r)>>1; if(p<=mid) insert(t[x].l, l, mid, p); else insert(t[x].r, mid+1, r, p); } void build() { for(int i=1; i<=n; i++) root[i]=root[i-1], insert(root[i], 1, *mp, val[ver[i]]);// printf("%d ",ver[i]);puts(""); } int kth(int x, int y, int k) { //printf("kth %d %d %d\n",x,y,k); x=root[x]; y=root[y]; int all = t[y].size-t[x].size; //printf("xy %d %d %d\n",x,y,all); if(k>all) return -1; k = all-k+1; int l=1, r=*mp; while(l!=r) { int lsize = t[lc(y)].size - t[lc(x)].size, mid=(l+r)>>1; if(k<=lsize) x=lc(x), y=lc(y), r=mid; else x=rc(x), y=rc(y), l=mid+1, k-=lsize; } return l; } }C; int main() { freopen("in","r",stdin); n=read(); m=read(); Q=read(); tot=n; for(int i=1; i<=n; i++) val[i]=mp[i]=read(), ufs::fa[i]=i; val[0]=1e9+5; for(int i=1; i<=m; i++) a[i].u=read(), a[i].v=read(), a[i].w=read(); Kruskal(); dfs(tot); sort(mp+1, mp+1+n); mp[0]=unique(mp+1, mp+1+n)-mp-1; for(int i=1; i<=n; i++) val[i] = lower_bound(mp+1, mp+1+mp[0], val[i])-mp; C.build(); int ans=0; for(int i=1; i<=Q; i++) { if(ans==-1) ans=0; u=read()^ans, lim=read()^ans, k=read()^ans; //u=read();lim=read();k=read(); for(int i=16; i>=0; i--) if(val[fa[u][i]]<=lim) u=fa[u][i]; ans = C.kth(L[u], R[u], k); if(ans!=-1) ans=mp[ans]; printf("%d\n",ans); } }
相关文章推荐
- bzoj3551 [ONTAK2010]Peaks加强版(Kruskal重构树+主席树)
- [bzoj3545+3551][ONTAK2010]Peaks&&加强版(离线+线段树合并)||(kruskal重构树&&dfs序+主席树)
- [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)
- bzoj 3551 [ONTAK2010]Peaks加强版(kruskal,主席树,dfs序)
- BZOJ 3551 ONTAK2010 Peaks加强版 Kruskal重构树+可持久化线段树
- bzoj 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+可持久化线段树
- 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树
- bzoj3551 [ONTAK2010]Peaks加强版(kruskal重构树+dfs序+主席树+树上倍增)
- 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增
- 【BZOJ3551】[ONTAK2010]Peaks加强版 最小生成树+DFS序+主席树
- 【BZOJ 3545】【ONTAK 2010】Peaks & 【BZOJ 3551】【ONTAK 2010】Peaks加强版 Kruskal重构树
- BZOJ 3551 ONTAK2010 Peaks加强版 Kruskal重构树+可持久化线段树
- bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树
- [主席树 Kruscal] BZOJ 3545 [ONTAK2010]Peaks & 3551 [ONTAK2010]Peaks加强版
- 3551: [ONTAK2010]Peaks加强版 kruskal重构树+dfs序+主席树
- 【bzoj3551】【ONTAK2010】【peaks加强版】【主席树】
- 3551 [ONTAK2010]Peaks加强版 kruskal重构树 可持久化线段树
- Bzoj3551:[ONTAK2010]Peaks加强版:Kruskal+主席树
- bzoj 3551: [ONTAK2010]Peaks加强版
- [BZOJ3551][ONTAK2010]Peaks加强版