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

    题目描述:

    bzoj3545luogu

    bzoj3551

    题解:

    重构树+线段树合并。

    可以算是板子了吧。

    代码(非强制在线):

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 100050;
    const int M = 5*N;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    int n,m,q,to[N],h[N];
    struct Pair
    {
        int x,y;
    }p[N];
    bool cmp(Pair a,Pair b){return a.x<b.x;}
    struct Edge
    {
        int x,y,w;
        void rd(){read(x),read(y),read(w);}
    }d[M];
    bool emp(Edge a,Edge b){return a.w<b.w;}
    int ff[N<<1],fa[N<<1][22],wg[N<<1],ch[N<<1][2];
    int findff(int u){return u==ff[u]?u:ff[u]=findff(ff[u]);}
    void kru()
    {
        wg[0] = 0x3f3f3f3f;
        for(int i=1;i<=(n<<1);i++)ff[i] = i;
        int tot = n,sum = 0;
        for(int i=1;i<=m&&sum<n-1;i++)
        {
            int x = findff(d[i].x),y = findff(d[i].y);
            if(x!=y)
            {
                ff[x]=ff[y]=fa[x][0]=fa[y][0]=++tot;
                wg[tot]=d[i].w;
                sum++;
                ch[tot][0]=x,ch[tot][1]=y;
            }
        }
    }
    void init()
    {
        for(int k=1;(1<<k)<=(n<<1);k++)
            for(int i=1;i<(n<<1);i++)
                fa[i][k]=fa[fa[i][k-1]][k-1];
    }
    int rt[N<<1];
    struct segtree
    {
        int siz[70*N],ls[70*N],rs[70*N],tot;
        void insert(int l,int r,int&u,int qx)
        {
            if(!u)u=++tot;siz[u]++;
            if(l==r)return ;
            int mid = (l+r)>>1;
            if(qx<=mid)insert(l,mid,ls[u],qx);
            else insert(mid+1,r,rs[u],qx);
        }
        int merge(int x,int y)
        {
            if(!(x*y))return x+y;
            int z = ++tot;
            siz[z] = siz[x]+siz[y];
            ls[z] = merge(ls[x],ls[y]);
            rs[z] = merge(rs[x],rs[y]);
            return z;
        }
        int query(int l,int r,int u,int qk)
        {
            if(l==r)return l;
            int tmp = siz[rs[u]],mid = (l+r)>>1;
            if(qk<=tmp)return query(mid+1,r,rs[u],qk);
            else return query(l,mid,ls[u],qk-tmp);
        }
    }tr;
    int main()
    {
    //    freopen("tt.in","r",stdin);
        read(n),read(m),read(q);
        for(int i=1;i<=n;i++)read(p[i].x),p[i].y=i;
        sort(p+1,p+1+n,cmp);
        for(int las=0x3f3f3f3f,k=0,i=1;i<=n;i++)
        {
            if(las!=p[i].x)
            {
                las = p[i].x;
                to[++k] = las;
            }
            h[p[i].y] = k;
        }
        for(int i=1;i<=m;i++)d[i].rd();
        sort(d+1,d+1+m,emp);
        kru();init();
        for(int i=1;i<=n;i++)tr.insert(1,n,rt[i],h[i]);
        for(int i=n+1;i<(n<<1);i++)rt[i]=tr.merge(rt[ch[i][0]],rt[ch[i][1]]);
        for(int u,w,k,i=1;i<=q;i++)
        {
            read(u),read(w),read(k);
            for(int j=20;j>=0;j--)if(wg[fa[u][j]]<=w)u=fa[u][j];
            if(tr.siz[rt[u]]<k)puts("-1");
            else printf("%d
    ",to[tr.query(1,n,rt[u],k)]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    匿名方法
    C# 正则表达式
    c# 预处理命令
    反射
    特性(attribute)
    c# 交换两个变量
    构造函数
    泛型
    Event事件
    委托
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10825678.html
Copyright © 2011-2022 走看看