제출 #1160378

#제출 시각아이디문제언어결과실행 시간메모리
1160378SmuggingSpunMosaic (IOI24_mosaic)C++20
37 / 100
220 ms106424 KiB
#include<bits/stdc++.h>
#include "mosaic.h"
using namespace std;
typedef long long ll;
vector<ll>mosaic(vector<int>X, vector<int>Y, vector<int>T, vector<int>B, vector<int>L, vector<int>R){
    int n = X.size(), q = T.size();
    vector<ll>ans(q);
    if(n <= 5000){
        vector<vector<int>>f(n + 1, vector<int>(n + 1, 0));
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= n; j++){
                if(i == 1){
                    f[i][j] = X[j - 1];
                }
                else if(j == 1){
                    f[i][j] = Y[i - 1];
                }
                else{
                    f[i][j] = (f[i][j - 1] | f[i - 1][j]) ^ 1;
                }
            }
        }
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= n; j++){
                f[i][j] += f[i][j - 1] + f[i - 1][j] - f[i - 1][j - 1]; 
            }
        }
        for(int i = 0; i < q; i++){
            ans[i] = f[B[i] + 1][R[i] + 1] - f[B[i] + 1][L[i]] - f[T[i]][R[i] + 1] + f[T[i]][L[i]];
        }
    }
    else if(*max_element(B.begin(), B.end()) == 0){
        for(int i = 1; i < n; i++){
            X[i] += X[i - 1];
        }
        for(int i = 0; i < q; i++){
            ans[i] = X[R[i]] - (L[i] == 0 ? 0 : X[L[i] - 1]);
        }
    }
    else if(*max_element(X.begin(), X.end()) == 0 && *max_element(Y.begin(), Y.end()) == 0){
        auto get = [&] (int u, int v){
            return u == -1 || v == -1 ? 0 : 1LL * ((u + 1) >> 1) * ((v + 1) >> 1) + 1LL * (u >> 1) * (v >> 1);
        };
        for(int i = 0; i < q; i++){
            ans[i] = get(B[i], R[i]) - get(T[i] - 1, R[i]) - get(B[i], L[i] - 1) + get(T[i] - 1, L[i] - 1);
        }
    }
    else{
        vector<int>row_1(n + 1), col_1(n + 1), row_2(n + 1), col_2(n + 1), row_3(n + 1), col_3(n + 1);
        vector<vector<int>>f(2, vector<int>(n + 1));
        row_1[0] = row_2[0] = row_3[0] = col_1[0] = col_2[0] = col_3[0] = 0;
        for(int i = 1; i <= n; i++){
            row_1[i] = row_1[i - 1] + (f[0][i] = X[i - 1]);
        }
        for(int i = 1; i <= n; i++){
            row_2[i] = row_2[i - 1] + (f[1][i] = (i == 1 ? Y[1] : ((f[0][i] | f[1][i - 1]) ^ 1)));
        }
        swap(f[0], f[1]);
        for(int i = 1; i <= n; i++){
            row_3[i] = row_3[i - 1] + (f[1][i] = (i == 1 ? Y[2] : ((f[0][i] | f[1][i - 1]) ^ 1)));
        }
        for(int i = 1; i <= n; i++){
            col_1[i] = col_1[i - 1] + (f[0][i] = Y[i - 1]);
        }
        for(int i = 1; i <= n; i++){
            col_2[i] = col_2[i - 1] + (f[1][i] = (i == 1 ? X[1] : ((f[0][i] | f[1][i - 1]) ^ 1)));
        }
        swap(f[0], f[1]);
        for(int i = 1; i <= n; i++){
            col_3[i] = col_3[i - 1] + (f[1][i] = (i == 1 ? X[2] : ((f[0][i] | f[1][i - 1]) ^ 1)));
        }
        vector<ll>pref_row_3(n + 1), pref_col_3(n + 1);
        pref_row_3[0] = pref_col_3[0] = 0;
        for(int i = 1; i <= n; i++){
            pref_row_3[i] = pref_row_3[i - 1] + max(0, row_3[i] - row_3[2]);
            pref_col_3[i] = pref_col_3[i - 1] + max(0, col_3[i] - col_3[2]);
        }
        function<ll(int, int)>get = [&] (int u, int v){
            if(++u == 0 || ++v == 0){
                return 0LL;
            }
            if(u == 1){
                return ll(row_1[v]);
            }
            else if(u == 2){
                return ll(row_1[v]) + row_2[v];
            }
            else if(v == 1){
                return ll(col_1[u]);
            }
            else if(v == 2){
                return ll(col_1[u]) + col_2[u];
            }
            ll ans = ll(row_1[v]) + row_2[v] + col_1[u] + col_2[u] - row_1[2] - row_2[2];
            ans += pref_row_3[v] - pref_row_3[max(2, v - u + 2)] + pref_col_3[u] - pref_col_3[max(2, u - v + 2)] - row_3[3] + row_3[2];
            return ans;
        };     
        for(int i = 0; i < q; i++){
            ans[i] = get(B[i], R[i]) - get(T[i] - 1, R[i]) - get(B[i], L[i] - 1) + get(T[i] - 1, L[i] - 1);
        }
    }
    return ans;
}
#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...