2019HDU multi-school Round10

 

11 Make Rounddog Happy (heuristic partition)

The meaning of problems: How many number statistical section 1e5 meet the maximum interval - interval length <= k and the number of the interval is not the same

Solution: This problem is said by this routine .... st pretreatment interval maximum value table and then pretreated for each right or left is not the same as the number of the number of the maximum distance

   Then each time interval of maximum violence enumeration find the answers range from the small side and then divide and conquer

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e6 + 5;
ll ans;
int n, K;
int a[MAXN];
int st[MAXN][21], lg[MAXN];
int L[MAXN], R[MAXN];
int vis[MAXN];

void solve(int l, int r) {
    if(l > r) return;

    int k = lg[r - l + 1];
    int pos;
    if(A [ST [L] [K]]> A = [ST [R & lt - ( . 1 << K) + . 1 ] [K]]) = POS ST [L] [K];
     the else POS ST = [R & lt - ( . 1 << K) + . 1 ] [K]; 

    IF (POS - L <= R & lt - POS) {
         for ( int I = L; I <= POS; I ++) {    // enumeration left point 
            int RR = A [pos] - I K + - . 1 ;   // after transposition satisfy rr <= range satisfying the right end is the meaning of the title 
            RR max = (RR, pos);             // is greater than the maximum established only pos 

            int TR = min (R & lt [I], R & lt);
             IF (TR> = RR) ANS 1LL + = * (TR - RR + . 1 ); 
        }
    } else {
        for(int i = r; i >= pos; i--) {
            int ll = K - a[pos] + i + 1;
            ll = min(ll, pos);

            int tl = max(L[i], l);
            if(tl <= ll) ans += 1LL * (ll - tl + 1);
        }
    }
    solve(l, pos - 1); solve(pos + 1, r);
}

int main() {
    lg[0] = -1;
    for(int i = 1; i <= MAXN - 2; i++) lg[i] = lg[i >> 1] + 1;

    int T;
    scanf("%d", &T);
    while(T--) {
        ans = 0;
        scanf("%d%d", &n, &K);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]), st[i][0] = i;

        for(int i = 1; i <= 20; i++)
            for(int j = 1; j <= n + 1 - (1 << i); j++) {
                if(a[st[j + (1 << (i - 1))][i - 1]] >= a[st[j][i - 1]]) st[j][i] = st[j + (1 << (i - 1))][i - 1];
                else st[j][i] = st[j][i - 1];
            }

        memset(vis, 0, sizeof(vis)); L[1] = 1; vis[a[1]] = 1;
        for(int i = 2; i <= n; i++) {
            if(vis[a[i]]) L[i] = max(L[i - 1], vis[a[i]] + 1);
            else L[i] = L[i - 1];
            vis[a[i]] = i;
        }

        memset(vis, 0, sizeof(vis)); R[n] = n; vis[a[n]] = n;
        for(int i = n - 1; i >= 1; i--) {
            if(vis[a[i]]) R[i] = min(R[i + 1], vis[a[i]] - 1);
            else R[i] = R[i + 1];
            vis[a[i]] = i;
        }
        solve(1, n);
        printf("%lld\n", ans);
    }
    return 0;
}
Make Rounddog Happy

 

Guess you like

Origin www.cnblogs.com/lwqq3/p/11449279.html