zoukankan      html  css  js  c++  java
  • [bzoj3551]Peaks加强版

    kruskal重构树,求出最小生成树,然后不断加边并新建节点作为两个联通块原根节点的父亲节点并作为新联通块的根(类似于不路径压缩的并查集),这样一来满足每一个节点所代表的边(除叶子节点外)父亲总时比儿子大,因此询问即在该重构树上的某一段点的第K大,用可持久化线段树维护,同时还要用倍增来确定该段的根节点。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 #define mid (l+r>>1)
     5 struct ji{
     6     int x,y,z;
     7     bool operator < (const ji &a)const{
     8         return z<a.z;
     9     }
    10 }a[5*N];
    11 int V,n,m,q,x,y,z,ans,r[N],id[N],ls[N],rs[N],ff[N],h[N],ma[N][21],f[N][21],tr[N*20],ch[N*20][2];
    12 int find(int k){
    13     if (k==ff[k])return k;
    14     return ff[k]=find(ff[k]);
    15 }
    16 void up(int k){
    17     tr[k]=tr[ch[k][0]]+tr[ch[k][1]];
    18 }
    19 void dfs(int k){
    20     for(int i=1;i<=20;i++){
    21         f[k][i]=f[f[k][i-1]][i-1];
    22         ma[k][i]=max(ma[k][i-1],ma[f[k][i-1]][i-1]);
    23     }
    24     if (!ls[k]){
    25         ls[k]=rs[k]=++id[0];
    26         id[id[0]]=k;
    27         return;
    28     }
    29     dfs(ls[k]);
    30     ls[k]=ls[ls[k]];
    31     dfs(rs[k]);
    32     rs[k]=rs[rs[k]];
    33 }
    34 int find(int k,int x){
    35     for(int i=20;i>=0;i--)
    36         if (ma[k][i]<=x)k=f[k][i];
    37     return k;
    38 }
    39 void update(int k1,int &k2,int l,int r,int x){
    40     k2=++V;
    41     if (l==r){
    42         tr[k2]=tr[k1]+1;
    43         return;
    44     }
    45     memcpy(ch[k2],ch[k1],8);
    46     if (x<=mid)update(ch[k1][0],ch[k2][0],l,mid,x);
    47     else update(ch[k1][1],ch[k2][1],mid+1,r,x);
    48     up(k2);
    49 }
    50 int query(int k1,int k2,int l,int r,int x){
    51     if (l==r)return l;
    52     int p=tr[ch[k2][1]]-tr[ch[k1][1]];
    53     if (p<x)return query(ch[k1][0],ch[k2][0],l,mid,x-p);
    54     return query(ch[k1][1],ch[k2][1],mid+1,r,x);
    55 }
    56 int main(){
    57     scanf("%d%d%d",&n,&m,&q);
    58     for(int i=1;i<=n;i++)scanf("%d",&h[i]);
    59     for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    60     sort(a+1,a+m+1);
    61     for(int i=1;i<2*n;i++)ff[i]=i;
    62     for(int i=1;i<=m;i++){
    63         x=find(a[i].x);
    64         y=find(a[i].y);
    65         if (x==y)continue;
    66         ff[x]=ff[y]=f[x][0]=f[y][0]=++n;
    67         ma[x][0]=ma[y][0]=a[i].z;
    68         ls[n]=x;
    69         rs[n]=y;
    70     }
    71     f[n][0]=n;
    72     dfs(n);
    73     for(int i=1;i<=n/2+1;i++)update(r[i-1],r[i],0,1e9,h[id[i]]);
    74     for(int i=1;i<=q;i++){
    75         scanf("%d%d%d",&x,&y,&z);
    76         x=find(x^ans,y^ans);
    77         z^=ans;
    78         ans=0;
    79         if (tr[r[rs[x]]]-tr[r[ls[x]-1]]<z)printf("-1
    ");
    80         else printf("%d
    ",ans=query(r[ls[x]-1],r[rs[x]],0,1e9,z));
    81     }
    82 }
    View Code
  • 相关阅读:
    .NET程序运行原理及基本概念详解
    c# 操作Redis的五种基本类型总结
    手写MQ框架(一)-准备启程
    手写MVC框架(二)-代码实现和使用示例
    手写DAO框架(七)-如何保证连接可用
    spring cloud入门
    maven学习整理
    mybatis入门学习
    spring事务使用探究
    微内核OS学习
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/11834635.html
Copyright © 2011-2022 走看看