bzoj3545 [ONTAK2010]Peaksbzoj3551 [ONTAK2010]Peaks加强版

Posted liguanlin1124

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3545 [ONTAK2010]Peaksbzoj3551 [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\n",to[tr.query(1,n,rt[u],k)]);
    }
    return 0;
}
View Code

 

以上是关于bzoj3545 [ONTAK2010]Peaksbzoj3551 [ONTAK2010]Peaks加强版的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3545ONTAK 2010Peaks & BZOJ 3551ONTAK 2010Peaks加强版 Kruskal重构树

[BZOJ3545][ONTAK2010]Peaks

bzoj3545[ONTAK2010]Peaks 线段树合并

Bzoj3545 [ONTAK2010]Peaks

bzoj3545: [ONTAK2010]Peaks 主席树合并

bzoj 3545/3551: [ONTAK2010]Peaks -- 主席树,最小生成树,倍增