zoukankan      html  css  js  c++  java
  • BZOJ3551 Peaks加强版

    kruskal重构树模板题

    简单介绍kruskal重构树

    就是对于原先的kruskal最小生成树算法进行扩展 每一次加入一条边就新建一个点并且将原先并查集合并即连边

    最后形成的树形图是所有原先存在的点都位于叶子 而新加的点即对应的边位于上方 这样的话就可以通过倍增来限制树上走过的边

    对于此题来说 我们需要询问静态子树第k大 那么就是显然的主席树上树问题 由于强制在线所以貌似kruskal重构树是比较好的办法

    注意数组别开太大 容易M qaq 然后BZ给我显示的T 我也是很郁闷qaq

    //Love and Freedom.
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define inf 20021225
    #define ll long long
    #define M 500010
    #define N 200010
    using namespace std;
    
    struct edge{int u,v,w;}e[M];
    struct _edge{int to,lt;}t[N<<1];
    int bel[N<<1],val[N<<1],id[N<<1],dfn[N<<1],cnt,in[N<<1],poi;
    void add(int x,int y,int v,int id){e[id].u=x;e[id].v=y;e[id].w=v;}
    void _add(int x,int y){t[++cnt].to=y; t[cnt].lt=in[x]; in[x]=cnt;}
    struct node{int ls,rs,s;};
    int n,m,q,nn;
    int read()
    {
        char ch; int s=0; ch=getchar();
        while(ch<'0'||ch>'9')    ch=getchar();
        while(ch>='0'&&ch<='9')    s=s*10+ch-'0',ch=getchar();
        return s;
    }
    struct sgt
    {
        node t[N*20];int rt[N<<1],poi;
        void pushup(int x){t[x].s=t[t[x].ls].s+t[t[x].rs].s;}
        void build(int &x,int l,int r)
        {
            if(l==r)    return;
            int mid=l+r>>1;
            build(t[x].ls,l,mid); build(t[x].rs,mid+1,r);    
        }
        void insert(int &x,int lt,int l,int r,int d)
        {
            x = ++poi; t[x] = t[lt];
            if(l==r){t[x].s++;return;}
            int mid=l+r>>1;
            if(d<=mid)    insert(t[x].ls,t[lt].ls,l,mid,d);
            else    insert(t[x].rs,t[lt].rs,mid+1,r,d);
            pushup(x);
        }
        int query(int x,int y,int l,int r,int d)
        {
            if(l==r)    return l;
            int s=t[t[y].rs].s-t[t[x].rs].s,mid=l+r>>1;;
            if(s>=d)    return query(t[x].rs,t[y].rs,mid+1,r,d);
            else    return query(t[x].ls,t[y].ls,l,mid,d-s);
        }
    }sgt;
    int find(int x)
    {
        if(!bel[x])    return x;
        return bel[x]=find(bel[x]);
    }
    bool cmp(edge a,edge b){return a.w<b.w;}
    void kruskal()
    {
        sort(e+1,e+m+1,cmp); poi=n;
        for(int i=1;i<=m;i++)
        {
            int x=e[i].u,y=e[i].v;
            int fx=find(x),fy=find(y);
            if(fx!=fy)
            {
                val[++poi]=e[i].w;
                _add(poi,fx); _add(poi,fy);
                bel[fx]=poi; bel[fy]=poi;
                if(poi == 2*n-1)    break;
            }
        }
    }
    int f[N<<1][18],idx,ed[N<<1];
    void dfs(int x)
    {
        for(int i=1;i<18;i++)    f[x][i]=f[f[x][i-1]][i-1];
        dfn[x]=++idx; id[idx]=x;
        if(x<=n)    sgt.insert(sgt.rt[idx],sgt.rt[idx-1],1,nn,val[x]);
        else    sgt.rt[idx]=sgt.rt[idx-1];
        for(int i=in[x];i;i=t[i].lt)
        {
            int y=t[i].to;// if(dfn[y])    continue;
            f[y][0]=x; dfs(y);
        }
        ed[x]=idx;
    }
    int find_pos(int x,int w)
    {
        for(int i=17;~i;i--)
            if(val[f[x][i]]<=w)    x=f[x][i];
        return x;
    }int h[N],r[N];
    int main()
    {
        n=read();m=read();q=read(); val[0]=inf*100;
        for(int i=1;i<=n;i++)
            h[i]=read(),r[i]=h[i];
        sort(r+1,r+n+1);nn=unique(r+1,r+n+1)-r-1;
        for(int i=1;i<=n;i++)
            val[i]=lower_bound(r+1,r+nn+1,h[i])-r;
        int x,y,w,k,lastans=0;
        for(int i=1;i<=m;i++)
        {
            x=read(),y=read(),w=read();
            add(x,y,w,i);
        }
        kruskal(); sgt.build(sgt.rt[0],1,nn);
        for(int i=1;i<=n;i++)    if(!dfn[i])    dfs(find(i));
        for(int i=1;i<=q;i++)
        {
            x=read();y=read();k=read();
            x^=lastans; y^=lastans; k^=lastans;    x=find_pos(x,y);
            if(sgt.t[sgt.rt[ed[x]]].s-sgt.t[sgt.rt[dfn[x]]].s<k)    printf("%d
    ",lastans=-1);
            else    printf("%d
    ",lastans=r[sgt.query(sgt.rt[dfn[x]],sgt.rt[ed[x]],1,nn,k)]);
            if(lastans==-1)    lastans=0;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    dvwa-Brute Force
    i春秋 Crypto模块rsa wrtiteup
    栈-函数调用
    Ymodem协议详解
    JAVA 传输post传输长字符、数据编码解码 反序列化字符串
    jquery datatable 全选,反选 参考文档
    java中bimface 在线申请token。模型视角 模型批注处理
    C# Winform 子窗体提交后更新父窗体datagridview数据(事件和委托)
    JAVA 两个时间 相差的 小时,天数,分钟
    JAVA 使用注解lombok@Builder和@Data,primary not found default constructor
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/10381607.html
Copyright © 2011-2022 走看看