【JZOJ3719】K-D-Sequence

description

We call a number kd as a good number of columns, and only after we after which add up the number of k, the number of columns of a sorting tolerance arithmetic sequence of d.

You have got a number of columns in a by n integers. Your task is to find its longest continuous substring, so as to satisfy the substring is good kd series.


analysis

  • Satisfying the condition \ ([l, r] \ ) sequences all the digital to analog \ (D \) the same as the remainder, not the same number, and the maximum value \ (- \) minimum \ (≤r-l + k +1 \)

  • \ (I \) cyclic scan again, and then maintains a monotonically increasing right point \ (J \) , found by the nature of the \ (I \) to the left of the right end point of the process is not the callback

  • Take a thing Maintenance \ ([i, j] \ ) maximum and minimum elements in the middle to support insertion and deletion, is relatively miss Ha Xijia segment tree, the query tree line half

  • Or write \ (set \) maintenance elements, the time complexity \ (O (n \ log n ) \)


code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<set>
#define MAXN 200005
#define INF 100000000000
#define ll long long
#define reg register ll
#define fo(i,a,b) for (i=a;i<=b;++i)
#define fd(i,a,b) for (i=a;i>=b;--i)

using namespace std;

ll n,k,d,i,j,ansl,ansr;
ll a[MAXN];
set<ll>s;

int main()
{
    freopen("sequence.in","r",stdin);
    freopen("sequence.out","w",stdout);
    scanf("%lld%lld%lld",&n,&k,&d);
    //fo(i,1,n)a[i]=read()+INF;
    fo(i,1,n)scanf("%lld",&a[i]),a[i]+=INF;
    if (!d)
    {
        i=1;
        while (i<=n)
        {
            j=i;
            while (a[i]==a[j+1] && j<n)++j;
            if (j-i>ansr-ansl)ansl=i,ansr=j;
            i=j+1;
        }
        printf("%lld %lld\n",ansl,ansr);
        return 0;
    }
    fo(i,1,n)
    {
        if (n-i<ansr-ansl)break;
        
        if (i<=j && j-i>=ansr-ansl)
        {
            set<ll>::iterator i1=s.begin(),i2=s.end();i2--;
            if ((*i2)-(*i1)<=j-i+1+k)ansl=i,ansr=j;
        }

        fo(j,j+1,n)
        {
            if (a[i]%d!=a[j]%d || s.count(a[j]/d))break;
            s.insert(a[j]/d);
            if (j-i>ansr-ansl)
            {
                set<ll>::iterator i1=s.begin(),i2=s.end();i2--;
                if ((*i2)-(*i1)<=j-i+1+k)ansl=i,ansr=j;
            }
        }
        s.erase(a[i]/d),--j;
    }
    printf("%lld %lld\n",ansl,ansr);
    return 0;
}

Guess you like

Origin www.cnblogs.com/horizonwd/p/12120685.html