Submission #1242453

#TimeUsernameProblemLanguageResultExecution timeMemory
1242453dostsMosaic (IOI24_mosaic)C++20
100 / 100
117 ms55240 KiB
#include "mosaic.h"
#include <bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2")
#define int long long
#define pii pair<int,int>
#define vi vector<int>
#define ff first
#define ss second
#define sp << " " <<
#define all(x) x.begin(),x.end()
#define big(x) ((int)(x.size()))
using namespace std;
const int MOD = 1e9+7, LIM = 1e6+1, inf = 2e9;

vi mosaic(vector<int32_t> X, vector<int32_t> Y,
                              vector<int32_t> T, vector<int32_t> B,
                              vector<int32_t> L, vector<int32_t> R) {
    int N = X.size();
    int Q = L.size();
    int until = min(N-1,5ll);
    vector<vi> rows(until+1,vi(N));
    vector<vi> cols(until+1,vi(N));
    for (int i = 0;i<N;i++) rows[0][i] = X[i],cols[0][i] = Y[i];
    for (int ii = 1;ii<=until;ii++) {
        rows[ii][0] = Y[ii];
        cols[ii][0] = X[ii];
        for (int i = 1;i<N;i++) rows[ii][i] = (!rows[ii][i-1] && !rows[ii-1][i]);
        for (int i = 1;i<N;i++) cols[ii][i] = (!cols[ii][i-1] && !cols[ii-1][i]);
    }
    vi ar(5*N+1,0),far,rar;
    for (int i = 1;i<=until;i++) {
        for (int j = 1;j<N;j++) {
            if (rows[i][j]) {
                ar[i-j+3*N] = 1;
            }
            if (cols[i][j]) {
                ar[j-i+3*N] = 1;
            }
        }
    }
    far = ar,rar = ar;
    rar[0] = 0;
    for (int i=1;i<=5*N;i++) rar[i] = rar[i-1]+ar[i]*i;
    far[0] = 5*N*ar[0];
    for (int i=1;i<=5*N;i++) far[i] = far[i-1]+ar[i]*(5*N-i+1);
    for (int i=1;i<=5*N;i++) ar[i]+=ar[i-1];
    auto duz = [&](int l,int r) {
        r = l+r-1;
        return ar[r]-ar[l-1];
    };
    auto rise = [&](int l,int r) {
        r = l+r-1;
        return rar[r]-rar[l-1]-(l-1)*duz(l,r-l+1);
    };
    auto fall = [&](int l,int r) {
        r = l+r-1;
        return far[r]-far[l-1]-(5*N-r)*duz(l,r-l+1);
    };
    for (int i = 0;i<=until;i++) {
        for (int j = 1;j<N;j++) rows[i][j] += rows[i][j-1],cols[i][j]+=cols[i][j-1];
    }
    auto sm = [&](vi& v,int l,int r) -> int {
        if (l > r) return 0;
        if (!l) return v[r];
        return v[r]-v[l-1];
    };
    vi ansy(Q);
    for (int ii = 0;ii<Q;ii++) {
        int ans = 0;
        while (L[ii] <= until && L[ii] <= R[ii]) {
            ans+=sm(cols[L[ii]],T[ii],B[ii]);
            L[ii]++;
        }
        while (T[ii] <= until && T[ii] <= B[ii]) {
            ans+=sm(rows[T[ii]],L[ii],R[ii]);
            T[ii]++;
        }
        if (L[ii] > R[ii] || B[ii] < T[ii]) {
            ansy[ii] = ans;
            continue;
        }
        int le = T[ii]-R[ii],ri = B[ii]-L[ii];
        int mn = min(B[ii]-T[ii]+1,R[ii]-L[ii]+1);
        ans+=rise(le+3*N,mn);
        ans+=fall(ri-mn+1+3*N,mn);
        ans+=mn*duz(le+mn+3*N,(ri-le+1)-2*mn);
        ansy[ii]=ans;
    } 

    return ansy;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...