• 【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
    ",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 }
  • 相关阅读:
    一手遮天 Android kotlin 协程: 通过 ticker 信道实现类似计时器的效果,协程的异常处理,解决协程的并发问题
    一手遮天 Android jetpack: LiveData 指定的对象的某个属性发生了变化时通知给观察者
    一手遮天 Android jetpack: DataBinding(MVVM)
    一手遮天 Android kotlin 协程: Channel(信道,用于在不同协程之间传输数据)
    一手遮天 Android jetpack: LiveData 基础,以及 LiveData 和 ViewModel 结合使用
    一手遮天 Android kotlin 协程: 协程基础(CoroutineScope, 为 CoroutineScope 扩展方法, runBlocking, launch, async, await, suspend, withContext, 设置/获取 CoroutineScope 的名称)
    一手遮天 Android UI: 监听配置变化(比如横竖屏切换等)
    一手遮天 Android jetpack: ViewModel 基础以及 viewModelScope
    一手遮天 Android Resource: 布局 xml 基础
    一手遮天 Android kotlin 协程: Flow(异步流,各种操作符的使用 buffer, conflate, collectLatest, drop, take, filter, map, transform, onEach, first, last, single, reduce, zip, combine, flatMapConcat, flatMapMerge 等)
  • 原文地址:https://www.cnblogs.com/myx12345/p/12019835.html
Copyright © 2020-2023  润新知