ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BZOJ3551 Peaks加强版 [Kruskal重构树,主席树]

2019-08-22 11:55:18  阅读:336  来源: 互联网

标签:加强版 rep read Kruskal ret BZOJ3551 int ll define


BZOJ

思路

我觉得这题可持久化线段树合并也可以做

我觉得这题建出最小生成树之后动态点分治+线段树也可以做

还是学习一下Kruskal重构树吧……

Kruskal重构树,就是在做最小生成树的时候,如果一条边\(e\)被选中了,就让那两个连通块的根都连向它,变成新的根。显然,最后会做出一个二叉树,其中叶子是点、非叶子节点是边,且边权形成了一个堆的形式。

分析一下性质,发现“用不超过某个权值的边构成的连通块”其实就是从一个点往上跳,最后的某一棵子树。

于是倍增+主席树区间k大,这题就做完了。

Kruskal重构树的例题还有[NOI2018]归程。只要知道这个东西那题似乎就一sb题……

代码

#include<bits/stdc++.h>
//clock_t t=clock();
namespace my_std{
    using namespace std;
//    #define pii pair<int,int>
//    #define fir first
//    #define sec second
//    #define MP make_pair
    #define rep(i,x,y) for (int i=(x);i<=(y);i++)
    #define drep(i,x,y) for (int i=(x);i>=(y);i--)
    #define go(x) for (int i=head[x];i;i=edge[i].nxt)
//    #define templ template<typename T>
    #define sz 606060
    typedef long long ll;
    typedef double db;
//    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//    templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
//    templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
//    templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
    inline void read(int& t)
    {
        t=0;char f=0,ch=getchar();double d=0.1;
        while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
        while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
        t=(f?-t:t);
    }
//    template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
//    char __sr[1<<21],__z[20];int __C=-1,__zz=0;
//    inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
//    inline void print(register int x)
//    {
//        if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
//        while(__z[++__zz]=x%10+48,x/=10);
//        while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
//    }
//    void file()
//    {
//        #ifdef NTFOrz
//        freopen("a.in","r",stdin);
//        #endif
//    }
//    inline void chktime()
//    {
//        #ifndef ONLINE_JUDGE
//        cout<<(clock()-t)/1000.0<<'\n';
//        #endif
//    }
//    #ifdef mod
//    ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
//    ll inv(ll x){return ksm(x,mod-2);}
//    #else
//    ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
//    #endif
//  inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;

int n,m,Q;
int val[sz],V[sz];
struct hhh{int u,v,w;const bool operator < (const hhh &x) const {return w<x.w;}}e[sz];
struct hh{int t,nxt;}edge[sz<<1];
int head[sz],ecnt;
void make_edge(int f,int t)
{
    edge[++ecnt]=(hh){t,head[f]};
    head[f]=ecnt;
    edge[++ecnt]=(hh){f,head[t]};
    head[t]=ecnt;
}

int rt;
int fa[sz][25],dfn[sz],low[sz],id[sz],T;
#define v edge[i].t
void dfs(int x,int f)
{
    id[dfn[x]=++T]=x;
    fa[x][0]=f;
    rep(i,1,20) fa[x][i]=fa[fa[x][i-1]][i-1];
    go(x) if (v!=f) dfs(v,x);
    low[x]=T;
}
#undef v

int f[sz];
int getfa(int x){return x==f[x]?x:f[x]=getfa(f[x]);}
void merge(int x,int y){f[x]=y;make_edge(x,y);}

int root[sz];
#define Tree sz*4
int size[Tree],ls[Tree],rs[Tree],cnt;
#undef Tree
#define lson ls[k],l,mid
#define rson rs[k],mid+1,r
void insert(int &k,int l,int r,int x,int pre)
{
    k=++cnt;size[k]=size[pre]+1;ls[k]=ls[pre],rs[k]=rs[pre];
    if (l==r) return;
    int mid=(l+r)>>1;
    if (x<=mid) insert(lson,x,ls[pre]);
    else insert(rson,x,rs[pre]);
}
int query(int k1,int k2,int l,int r,int K)
{
    if (l==r) return l;
    int mid=(l+r)>>1,S=size[rs[k2]]-size[rs[k1]];
    if (S>=K) return query(rs[k1],rs[k2],mid+1,r,K);
    return query(ls[k1],ls[k2],l,mid,K-S);
}

int main()
{
//    file();
    read(n),read(m),read(Q);
    rep(i,1,n) read(val[i]),V[i]=val[i];
    sort(V+1,V+n+1);int _n=unique(V+1,V+n+1)-V-1;
    rep(i,1,n) val[i]=lower_bound(V+1,V+_n+1,val[i])-V;
    int x,y,z;
    rep(i,1,m) read(x),read(y),read(z),e[i]=(hhh){x,y,z};
    sort(e+1,e+m+1);
    rep(i,1,n+m) f[i]=i;
    rep(i,1,m)
    {
        x=e[i].u,y=e[i].v;
        x=getfa(x),y=getfa(y);
        if (x==y) continue;
        merge(x,i+n),merge(y,i+n);
    }
    rt=getfa(1);
    dfs(rt,0);
    rep(i,1,n+n-1) if (id[i]<=n) insert(root[i],1,n,val[id[i]],root[i-1]); else root[i]=root[i-1];
    int ans=-1;
    while (Q--)
    {
        read(x),read(y),read(z);
        if (ans!=-1) x^=ans,y^=ans,z^=ans;
        drep(i,20,0) if (fa[x][i]&&e[fa[x][i]-n].w<=y) x=fa[x][i];
        if (size[root[low[x]]]-size[root[dfn[x]-1]]<z) ans=-1;
        else ans=V[query(root[dfn[x]-1],root[low[x]],1,n,z)];
        printf("%d\n",ans);
    }
    return 0;
}

标签:加强版,rep,read,Kruskal,ret,BZOJ3551,int,ll,define
来源: https://www.cnblogs.com/p-b-p-b/p/11393467.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有