19徐州网络赛E 线段树加离散化

Posted chen99

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了19徐州网络赛E 线段树加离散化相关的知识,希望对你有一定的参考价值。

题目链接:https://www.jisuanke.com/contest/3005/267806

 

 

按wi的值建立权值线段树维护值为wi出现的最后位置,对于第i个人的答案,查询线段树[wi+m,max]区间的最大位置pos,令如果pos-i-1小于等于-1则是在i之后不存在大于等于wi+m的人,否则第i个人的答案即为pos-i-1。由于wi范围过大所以需对wi离散化

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
#define maxn 1000010
int n,m,mx[maxn<<2];
ll w[maxn],x[maxn],li[maxn],ans[maxn];
void pushup(int rt)
{
    mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
}
void update(int L,int c,int l,int r,int rt)
{
    if(l==r)
    {
        mx[rt]=c;
        return ;
    }
    int mid=l+r>>1;
    if(L<=mid)update(L,c,ls);
    else update(L,c,rs);
    pushup(rt);
}
int query(int L,int R,int c,int l,int r,int rt)
{
    if(L<=l&&R>=r)
    {
        return mx[rt];
    }
    int mid=l+r>>1,ret=0;
    if(L<=mid)ret=max(ret,query(L,R,c,ls));
    if(R>mid)ret=max(ret,query(L,R,c,rs));
    return ret;
}
int main()
{
    scanf("%d%d",&n,&m);
    int tot=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&w[i]);
        x[++tot]=w[i];
        x[++tot]=w[i]+m;
    }
    sort(x+1,x+1+tot);
    int nx=unique(x+1,x+1+tot)-x-1;
    int L;
    for(int i=1;i<=n;i++)
    {
        L=lower_bound(x+1,x+1+nx,w[i])-x;
        update(L,i,1,nx,1);
    }
    for(int i=1;i<=n;i++)
    {
        L=lower_bound(x+1,x+1+nx,w[i]+m)-x;
        L=query(L,nx,i,1,nx,1);
        if(L==-1)ans[i]=-1;
        else ans[i]=L-i-1;
        if(ans[i]<-1)ans[i]=-1;
    }
    for(int i=1;i<n;i++)
    printf("%lld ",ans[i]);
    printf("%lld
",ans[n]);
    return 0;
}

 

以上是关于19徐州网络赛E 线段树加离散化的主要内容,如果未能解决你的问题,请参考以下文章

HDU6447 YJJ's Salesman-2018CCPC网络赛-线段树求区间最值+离散化+dp

2019徐州网络赛 XKC's basketball team 线段树

徐州网络赛2018

2016安徽省赛 - 木条染色 离散化+线段树

徐州网络赛B-BE,GE or NE记忆化搜索博弈论

2018徐州网络赛B题 BE, GE or NE (博弈记忆化搜索)