Editorial for VM 14 Bài 05 - Quá béo


Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.

Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này

Code mẫu của ladpro98

#include <bits/stdc++.h>
const int N = 1000006;
using namespace std;
int a[N];
int n, L, D;
deque<int> ma, mi;

int main()
{
    int i, j;
    scanf("%d %d %d", &n, &L, &D); L++;
    for(i=1; i<=n; i++) scanf("%d", &a[i]);
    j = 1; long long res = 0;
    for(i=1; i<=n; i++) {
        while (!ma.empty() && a[ma.back()] <= a[i]) ma.pop_back();
        while (!mi.empty() && a[mi.back()] >= a[i]) mi.pop_back();
        ma.push_back(i); mi.push_back(i);
        while (a[ma.front()] - a[mi.front()] > D) {
            j++;
            if (ma.front() < j) ma.pop_front();
            if (mi.front() < j) mi.pop_front();
        }
        if (j <= (i - L + 1))
            res += (i - j + 1) - (L - 1);
    }
    cout << res;
    return 0;
}

Code mẫu của skyvn97

#include<bits/stdc++.h>
#define MAX    1000100
#define FOR(i,a,b) for (int i=(a);i<=(b);i=i+1)
#define MASK(i) (1<<(i))
using namespace std;
typedef long long ll;
int mx[MAX][21],mn[MAX][21];
int a[MAX],lg2[MAX];
int n,l,d;
void init(void) {
    scanf("%d%d%d",&n,&l,&d);
    FOR(i,1,n) scanf("%d",&a[i]);
}
void setuprmq(void) {
    FOR(i,1,n) mx[i][0]=mn[i][0]=a[i];
    FOR(j,1,20) FOR(i,1,n-MASK(j)+1) {
        mx[i][j]=max(mx[i][j-1],mx[i+MASK(j-1)][j-1]);
        mn[i][j]=min(mn[i][j-1],mn[i+MASK(j-1)][j-1]);
    }
    FOR(i,1,n) {
        while (MASK(lg2[i])<=i) lg2[i]++;
        lg2[i]--;
    }
}
int findmax(int l,int r) {
    int k=lg2[r-l+1];
    return (max(mx[l][k],mx[r-MASK(k)+1][k]));
}
int findmin(int l,int r) {
    int k=lg2[r-l+1];
    return (min(mn[l][k],mn[r-MASK(k)+1][k]));
}
int range(int s) {
    int l=0;
    int r=n-s;
    while (true) {
        if (l==r) return (l);
        if (r-l==1) return ((findmax(s,s+r)-findmin(s,s+r)<=d)?r:l);
        int m=(l+r)>>1;
        if (findmax(s,s+m)-findmin(s,s+m)<=d) l=m; else r=m-1;
    }
}
void process(void) {
    ll res=0;
    FOR(i,1,n) {
        int t=range(i);
        //printf("RANGE %d is %d\n",i,t);
        if (t>=l) res+=t-l+1;
    }
    cout<<res;
}
int main(void) {
    init();
    setuprmq();
    process();
    return 0;
}

Comments

Please read the guidelines before commenting.


There are no comments at the moment.