제출 #1325011

#제출 시각아이디문제언어결과실행 시간메모리
1325011vladiliusGarden (JOI23_garden)C++20
75 / 100
3092 ms13488 KiB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
#define pb push_back
#define ff first
#define ss second

struct dsu{
    vector<int> sz, p;
    int n, mx;
    dsu(int ns){
        n = ns;
        p.resize(n + 1);
        sz.resize(n + 1);
        mx = 1;
        for (int i = 1; i <= n; i++){
            sz[i] = 1;
            p[i] = i;
        }
    }
    void clear(){
        mx = 1;
        for (int i = 1; i <= n; i++){
            sz[i] = 1;
            p[i] = i;
        }
    }
    int get(int v){
        if (p[v] != v){
            p[v] = get(p[v]);
        }
        return p[v];
    }
    void unite(int x, int y){
        x = get(x); y = get(y);
        if (x == y) return;
        if (sz[x] > sz[y]) swap(x, y);
        p[x] = y;
        sz[y] += sz[x];
    }
};

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    
    int n, m, d; cin>>n>>m>>d;
    vector<bool> f(d + 2), ban(d + 2); f[0] = f[d + 1] = 1;
    vector<int> s(2 * d), M[2 * d];
    
    int L1 = 1e9, R1 = 0;
    for (int i = 1; i <= n; i++){
        int x, y; cin>>x>>y;
        y++;
        s[x]++; s[x + d]++;
        f[y] = ban[y] = 1;
        L1 = min(L1, y); R1 = max(R1, y);
    }
    
    vector<int> D[2 * d];
    for (int i = 1; i <= m; i++){
        int x, y; cin>>x>>y;
        y++;
        if (ban[y]) continue;
        f[y] = 1;
        M[x].pb(y);
        M[x + d].pb(y);
    }
    
    vector<bool> W = f;
    
    vector<int> F[d + 1];
    for (int i = 0; i < 2 * d; i++){
        for (int y: M[i]){
            if (F[y].empty() || F[y].back() < i) F[y].pb(i);
        }
    }
    
    for (int i = 1; i <= d; i++) reverse(F[i].begin(), F[i].end());
    
    vector<int> Q[2 * d];
    
    dsu T(d);
    
    vector<int> L(d), R(d); L[d - 1] = 1e9;
    
    ll out = 1e18;
    for (int i = 0; i < d; i++){
        for (int j = 1; j <= d; j++) f[j] = W[j];

        int A = d;
        
        auto rem = [&](int x){
            if (f[x]) return;
            A--;
            if (!f[x - 1]) T.unite(x - 1, x);
            if (!f[x + 1]) T.unite(x, x + 1);

            int v = T.get(x);
            T.mx = max(T.mx, T.sz[v] + 1);
        };
        
        for (int j = 1; j <= d; j++){
            if (!f[j]){
                rem(j);
            }
        }
        
        auto get = [&](){
            if (A <= 1) return d;
            return T.mx;
        };
        
        for (int j = d - 2; j >= 0; j--){
            L[j] = L[j + 1]; R[j] = R[j + 1];
            for (int y: M[i + j + 1]){
                L[j] = min(L[j], y);
                R[j] = max(R[j], y);
            }
        }
        
        for (int j = 1; j <= d; j++){
            if (ban[j]) continue;
            int Y = -1;
            while (!F[j].empty() && F[j].back() < (i + d)){
                Y = F[j].back();
                F[j].pop_back();
            }
            if (Y >= 0) F[j].pb(Y);
            
            if (!F[j].empty()){
                Q[F[j].back()].pb(j);
            }
        }

        int cc = 0;
        for (int j = i; j < i + d; j++){
            for (int y: Q[j]){
                f[y] = 0;
                rem(y);
            }
            Q[j].clear();
            cc += s[j];
            if (cc == n){
                int L2 = min(L1, L[j - i]), R2 = max(R1, R[j - i]), Y = min((d + 1) - get(), R2 - L2 + 1);
                out = min(out, 1LL * (j - i + 1) * Y);
            }
        }
        
        T.clear();
    }
    
    cout<<out<<"\n";
}
#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...