J-Distance ZOJ-4003(デュアルポインター)

ここに写真の説明を挿入
質問:
2つのベクトル間距離は∑ ∣ a [i] − b [i] ∣ p ∑ | a [i] -b [i] | ^ pa [ i ]b [ i ] p
2つの配列がある場合、2つの配列のそれぞれが(同じ長さの)ベクトルとしてサブ配列を取得し、距離がvを超えないように、サブベクトルのペアの数を見つけます。

アイデア:
2つのサブアレイの開始点の違いを列挙してから、ダブルポインターを維持します。
一度[l1、r 1] −> [l 2、r 2] [l1、r1]-> [l2、r2][ l 1 R 1 ] ->>[ L 2 r 2 ]この間隔が満たされると、[l 11、r 1] −> [l 22、r 2]は、l 1 <l11≤r1、l 2 <l22≤r2[l11、r1]-を満たします。 > [l22、r2]、l1 <l11≤r1、l2 <l22≤r2を満たす[ l 1 1 R 1 ] ->>[ L 2 2 R&LT 2 ] フルフットL 1<l 1 1r 1 l 2<l 2 2r 2、ここには単調性があります。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

typedef long long ll;
const int maxn = 4e5 + 7;

ll a[maxn],b[maxn];
ll qpow(ll x,ll n) {
    
    
    ll res = 1;
    for(int i = 1;i <= n;i++) {
    
    
        res *= x;
    }
    return res;
}

int main() {
    
    
    int T;scanf("%d",&T);
    while(T--) {
    
    
        ll n,v,p;scanf("%lld%lld%lld",&n,&v,&p);
        for(int i = 1;i <= n;i++) {
    
    
            scanf("%lld",&a[i]);
        }
        for(int i = 1;i <= n;i++) {
    
    
            scanf("%lld",&b[i]);
        }
        ll ans = 0;
        for(int len = 0;len <= n - 1;len++) {
    
     //两个指针的差距
            int l1 = 1,r1 = 1; //第一个人的指针
            int l2 = 1 + len,r2 = 1 + len; //第二个人的指针
            ll tmp = qpow(abs(a[l1] - b[l2]),p);
            while(r2 <= n) {
    
    
                if(tmp <= v) {
    
    
                    ans += r1 - l1 + 1;
                    r2++;
                    r1++;
                    tmp += qpow(abs(a[r1] - b[r2]),p);
                } else {
    
    
                    tmp -= qpow(abs(a[l1] - b[l2]),p);
                    l1++;
                    l2++;
                    if(l1 > r1) {
    
    
                        r1++;
                        r2++;
                        tmp += qpow(abs(a[r1] - b[r2]),p);
                    }
                }
            }
            
            if(len == 0) continue;
            l1 = 1 + len,r1 = 1 + len;
            l2 = 1,r2 = 1;
            tmp = qpow(abs(a[l1] - b[l2]),p);
            while(r1 <= n) {
    
    
                if(tmp <= v) {
    
    
                    ans += r1 - l1 + 1;
                    r2++;
                    r1++;
                    tmp += qpow(abs(a[r1] - b[r2]),p);
                } else {
    
    
                    tmp -= qpow(abs(a[l1] - b[l2]),p);
                    l1++;
                    l2++;
                    if(l1 > r1) {
    
    
                        r1++;
                        r2++;
                        tmp += qpow(abs(a[r1] - b[r2]),p);
                    }
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/tomjobs/article/details/109072832