【線段樹】 HDU 5289 Assignment

點擊打開鏈接

對於第i個數,最多有 i個以i爲R端的區間可以選

前面維護好一個L值 表示在L之前都不滿足條件的位置

然後對於L-R二分

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <vector>
typedef long long  LL;
using namespace std;
const LL mod=1e9+7;
const int MAXN = 101000;//點數的最大值
const int MAXM = 160000;//邊數的最大值
const int INF = 0x3f3f3f3f;
#define lson l,m, rt<<1
#define rson m+1,r,rt<<1|1
int read()
{
    char ch=' ';
    int ans=0;
    while(ch<'0' || ch>'9')
        ch=getchar();
    while(ch<='9' && ch>='0')
    {
        ans=ans*10+ch-'0';
        ch=getchar();
    }
    return ans;
}
int ans[MAXN<<2][2],x[MAXN];
void pushup(int rt)
{
    ans[rt][0]=max(ans[rt<<1][0],ans[rt<<1|1][0]);
    ans[rt][1]=min(ans[rt<<1][1],ans[rt<<1|1][1]);
}
void build(int l,int r,int rt)
{
    if(l==r)
    {
        x[l]=read();
        ans[rt][0]=ans[rt][1]=x[l];
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
int querymax(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
        return ans[rt][0];
    int m=(l+r)>>1;
    int res=-INF;
    if(L<=m) res=max(res,querymax(L,R,lson));
    if(R>m) res=max(res,querymax(L,R,rson));
    return res;
}
int querymin(int L,int R,int l,int r,int rt)
{
    if(L<=l&&r<=R)
        return ans[rt][1];
    int m=(l+r)>>1;
    int res=INF;
    if(L<=m) res=min(res,querymin(L,R,lson));
    if(R>m) res=min(res,querymin(L,R,rson));
    return res;
}
int k,n;
int erfen(int L,int now,int orz)
{
    int l=L,r=now,ans;
    while(l<=r)
    {
        int m=(l+r)>>1;
        if(querymax(m,now,1,n,1)-orz<k&&orz-querymin(m,now,1,n,1)<k)
        {
            r=m-1;
            ans=m;
        }
        else l=m+1;
    }
    return ans;
}
int main()
{
    int t;
//    freopen("in.txt","r",stdin);
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&k);
        build(1,n,1);
        int L=1;
        LL ans=0;
        for(int i=1;i<=n;i++)
        {
            if (((querymax(L,i,1,n,1)-x[i])>=k)||(x[i]-querymin(L,i,1,n,1))>=k)
            {
                int xx=0;
                xx=erfen(L,i,x[i]);
                L=xx;
                ans+=i-xx+1LL;
            }
            else
                ans+=i-L+1;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章