Cod sursa(job #1878247)

Utilizator alex_HarryBabalau Alexandru alex_Harry Data 13 februarie 2017 23:04:40
Problema Magazin Scor 0
Compilator cpp Status done
Runda Lista lui wefgef Marime 1.61 kb
#include <fstream>
using namespace std;
ifstream f("friendcross.in");
ofstream g("friendcross.out");
int N, K;
int A[100005], B[100005], Poz[100005], Poz2[100005];
int Arb[259][100005], Cnt[100005];
int Block[100005], Start[100005];
const int limit = 1000;
void Update(int ind, int poz)
{
    while(poz <= N)
    {
        Arb[ind][poz]++;
        poz += (poz & (-poz));
    }
}
void precalcBlock()
{
    int b = 1, cnt = 0;
    Start[1] = 1;
    for(int i = 1; i <= N; i++)
    {
        ++cnt;
        if(cnt == limit + 1)
        {
            cnt = 1;
            b++;
            Start[b] = i;
        }
        Block[i] = b;
    }
}
int Sum(int ind, int poz)
{
    int ans = 0;
    while(poz >= 1)
    {
        ans += Arb[ind][poz];
        poz -= (poz & (-poz));
    }
    return ans;
}


void Read()
{
    f >> N >> K;
    for(int i = 1; i <= N; i++)
        f >> A[i], Poz2[A[i]] = i;
    for(int i = 1; i <= N; i++)
        f >> B[i], Poz[B[i]] = i;
}

void Solve()
{
    long long ans = 0;
    for(int i = N; i >= 1; i--)
    {
        int left = max(0, A[i] - K - 1), right = min(N + 1, A[i] + K + 1);
        for(int j = 1; j <= Block[Poz[A[i]] - 1] - 1; j++)
            ans += Sum(j, left) + Cnt[j] - Sum(j, right - 1);
        for(int j = Start[Block[Poz[A[i]] - 1]]; j < Poz[A[i]]; j++)
            if(Poz2[B[j]] > i && (B[j] >= right || B[j] <= left))
                ans++;
        Update(Block[Poz[A[i]]], A[i]);
        Cnt[Block[Poz[A[i]]]]++;
    }
    g << ans << "\n";
}


int main()
{
    Read();
    precalcBlock();
    Solve();
    return 0;
}