zoukankan      html  css  js  c++  java
  • BZOJ 3545/BZOJ 3551 Peaks

    kruskal重构树。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define maxv 200050
    #define maxe 2000050
    #define inf 2147483647
    using namespace std;
    struct edges
    {
        int u,v,w;
    }es[maxe];
    struct edge
    {
        int v,nxt;
    }e[maxe];
    int n,m,q,h[maxv],hash[maxv],x,y,z,lastans=0,val[maxv],g[maxv],nume=0,father[maxv];
    int dis[maxv],l[maxv],r[maxv],fdfn[maxv],anc[maxv][21],times=0;
    int root[maxv],tot=0,tots=0,ls[maxv*23],rs[maxv*23],sum[maxv*23],len;
    bool cmp(edges x,edges y)
    {
        return x.w<y.w;
    }
    int read()
    {
        char ch;int data=0;
        while (ch<'0' || ch>'9') ch=getchar();
        while (ch>='0' && ch<='9')
        {
            data=data*10+ch-'0';
            ch=getchar();
        }
        return data;
    }
    void addedge(int u,int v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    int getfather(int x)
    {
        if (father[x]!=x) father[x]=getfather(father[x]);
        return father[x];
    }
    void kruskal_tree()
    {
        sort(es+1,es+m+1,cmp);
        for (int i=1;i<=2*n;i++) father[i]=i;
        for (int i=1;i<=m;i++)
        {
            int u=es[i].u,v=es[i].v,w=es[i].w;
            int f1=getfather(es[i].u),f2=getfather(es[i].v);
            if (f1!=f2)
            {
                tot++;
                father[f1]=tot;father[f2]=tot;val[tot]=es[i].w;
                addedge(f1,tot);addedge(tot,f1);addedge(f2,tot);addedge(tot,f2);
            }
        }
    }
    void dfs(int x)
    {
        int flag=0;l[x]=inf;r[x]=0;
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (anc[x][0]!=v)
            {
                flag=1;
                anc[v][0]=x;dis[v]=dis[x]+1;
                dfs(v);
                l[x]=min(l[x],l[v]);r[x]=max(r[x],r[v]);
            }
        }
        if (!flag)
        {
            l[x]=r[x]=++times;
            fdfn[times]=x;
        }
    }
    void get_table()
    {
        for (int e=1;e<=20;e++)
            for (int i=1;i<=tot;i++)
                anc[i][e]=anc[anc[i][e-1]][e-1];
    }
    int bnd(int x)
    {
        return lower_bound(hash+1,hash+len+1,x)-hash;
    }
    void insert(int last,int &now,int left,int right,int pos)
    {
        now=++tots;sum[now]=sum[last]+1;
        if (left==right) return;
        ls[now]=ls[last];rs[now]=rs[last];
        int mid=left+right>>1;
        if (pos<=mid) insert(ls[last],ls[now],left,mid,pos);
        else insert(rs[last],rs[now],mid+1,right,pos);
    }
    void build_seg()
    {
        sort(hash+1,hash+n+1);
        len=unique(hash+1,hash+n+1)-hash-1;
        for (int i=1;i<=n;i++)
            insert(root[i-1],root[i],1,len,bnd(h[fdfn[i]]));
    }
    int find(int x,int k)
    {
        for (int e=20;e>=0;e--)
        {
            if ((val[anc[x][e]]<=k) && (anc[x][e]))
                x=anc[x][e];
        }
        return x;
    }
    int ask(int last,int now,int left,int right,int k)
    {
        if (left==right) return hash[left];
        int mid=left+right>>1;
        int r=sum[rs[now]]-sum[rs[last]];
        if (r>=k) return ask(rs[last],rs[now],mid+1,right,k);
        else return ask(ls[last],ls[now],left,mid,k-r);
    }
    void work()
    {
        x=read();y=read();z=read();
        x^=lastans;y^=lastans;z^=lastans;
        int k=find(x,y);
        if (r[k]-l[k]+1<z) {printf("-1
    ");lastans=0;}
        else 
        {
            lastans=ask(root[l[k]-1],root[r[k]],1,len,z);
            printf("%d
    ",lastans);
        }
    }
    int main()
    {
        n=read();m=read();q=read();tot=n;
        for (int i=1;i<=n;i++) {h[i]=read();hash[i]=h[i];}
        for (int i=1;i<=m;i++) {es[i].u=read();es[i].v=read();es[i].w=read();}
        kruskal_tree();
        dfs(tot);
        get_table();
        build_seg();
        for (int i=1;i<=q;i++)
            work();
        return 0;
    }
  • 相关阅读:
    适合程序员的两样工具-续集
    JavaScript之面向对象1
    人类简史笔记摘录
    做正确的事
    个人高效率任务列表
    视频技术基础
    了解更多梭罗与瓦尔登湖
    禅与摩托车维修的艺术
    人工智能发展及算法
    互联网没能降低房价,人工智能就可以不?
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5881487.html
Copyright © 2011-2022 走看看