제출 #1234824

#제출 시각아이디문제언어결과실행 시간메모리
1234824GeforgsI want to be the very best too! (NOI17_pokemonmaster)C++20
47 / 100
1289 ms589824 KiB
#include <iostream>
#include <iomanip>
#include <vector>
#include <cmath>
#include <algorithm>
#include <set>
#include <queue>
#include <map>
#include <unordered_map>
#include <stack>
#include <bitset>
#include <string>
#include <cstring>
#include <iterator>
#include <random>
#define ll long long
#define ld long double
#define inf (ll)(2*1e18)
#define sort(a) sort(a.begin(), a.end())
#define reverse(a) reverse(a.begin(), a.end())
#define pb push_back
#define endl "\n"
using namespace std;

const ll dim = 20;

struct Node{
    ll left=-1, right=-1, sum=0;
};

pair<ll, ll> get(pair<ll, ll> x, vector<vector<pair<ll, ll>>>& parent){
    if(parent[x.first][x.second] == x) return x;
    return parent[x.first][x.second] = get(parent[x.first][x.second], parent);
}

void unite(pair<ll, ll> x, pair<ll, ll> y, vector<vector<pair<ll, ll>>>& parent, vector<vector<vector<pair<ll, ll>>>>& children){
    x = get(x, parent);
    y = get(y, parent);
    if(x == y) return;
    parent[y.first][y.second] = x;
    children[x.first][x.second].pb(y);
}

void DFS(pair<ll, ll> id, pair<ll, ll> last, ll& time, vector<vector<vector<pair<ll, ll>>>>& children, vector<vector<vector<pair<ll, ll>>>>& up, vector<vector<ll>>& tin, vector<vector<ll>>& tout){
    tin[id.first][id.second] = ++time;
    up[id.first][id.second][0] = last;
    for(int i=1;i<dim;++i){
        up[id.first][id.second][i] = up[up[id.first][id.second][i-1].first][up[id.first][id.second][i-1].second][i-1];
    }
    for(auto el: children[id.first][id.second]){
        DFS(el, id, time, children, up, tin, tout);
    }
    tout[id.first][id.second] = time;
}

void add(ll id, ll l, ll r, ll pos, ll val, vector<Node>& nodes){
    if(id == -1) return;
    nodes[id].sum += val;
    if(l == r) return;
    ll m=(l+r)/2;
    if(pos <= m){
        if(nodes[id].left == -1){
            nodes[id].left = nodes.size();
            nodes.pb(Node());
        }
        add(nodes[id].left, l, m, pos, val, nodes);
    }else{
        if(nodes[id].right == -1){
            nodes[id].right = nodes.size();
            nodes.pb(Node());
        }
        add(nodes[id].right, m+1, r, pos, val, nodes);
    }
}

ll get(ll id, ll l, ll r, ll x, vector<Node>& nodes){
    if(l == r) return 0;
    ll m=(l+r)/2;
    if(x <= m){
        ll res=0;
        if(nodes[id].left != -1){
            res += get(nodes[id].left, l, m, x, nodes);
        }
        if(nodes[id].right != -1){
            res += nodes[nodes[id].right].sum;
        }
        return res;
    }
    ll res=0;
    if(nodes[id].right != -1){
        res += get(nodes[id].right, m+1, r, x, nodes);
    }
    return res;
}

void add(ll id, ll l, ll r, ll x, ll pos, ll val, vector<ll>& c, vector<Node>& nodes){
    add(c[id], 0, 1e6, pos, val, nodes);
    if(l == r) return;
    ll m=(l+r)/2;
    if(x <= m) add(2*id, l, m, x, pos, val, c, nodes);
    else add(2*id + 1, m+1, r, x, pos, val, c, nodes);
}

ll get(ll id, ll l, ll r, ll tl, ll tr, ll x, vector<ll>& c, vector<Node>& nodes){
    if(r < tl or tr < l) return 0;
    if(tl <= l and r <= tr){
        return get(c[id], 0, 1e6, x, nodes);
    }
    ll m=(l+r)/2;
    return get(2*id, l, m, tl, tr, x, c, nodes) + get(2*id+1, m+1, r, tl, tr, x, c, nodes);
}

pair<ll, ll> get(pair<ll, ll> x, ll val, vector<vector<ll>>& L, vector<vector<vector<pair<ll, ll>>>>& up){
    for(int i=dim-1;i>=0;--i){
        if(L[up[x.first][x.second][i].first][up[x.first][x.second][i].second] <= val){
            x = up[x.first][x.second][i];
        }
    }
    return x;
}

void solve(){
    ll n, m, q, i, j, time=-1, x, y, val, type, pos;
    pair<ll, ll> last;
    cin>>n>>m>>q;
    vector<vector<ll>> L(n, vector<ll>(m));
    vector<vector<ll>> P(n, vector<ll>(m));
    vector<vector<pair<ll, ll>>> parent(n, vector<pair<ll, ll>>(m));
    vector<vector<vector<pair<ll, ll>>>> children(n, vector<vector<pair<ll, ll>>>(m));
    vector<vector<vector<pair<ll, ll>>>> up(n, vector<vector<pair<ll, ll>>>(m, vector<pair<ll, ll>>(dim)));
    map<ll, vector<pair<ll, ll>>> level;
    map<ll, set<ll>> next;
    vector<vector<ll>> tin(n, vector<ll>(m));
    vector<vector<ll>> tout(n, vector<ll>(m));
    for(i=0;i<n;++i){
        for(j=0;j<m;++j){
            cin>>L[i][j];
            level[L[i][j]].pb({i, j});
            parent[i][j] = {i, j};
        }
    }
    for(i=0;i<n;++i){
        for(j=0;j<m;++j){
            cin>>P[i][j];
            next[P[i][j]].insert(1e6);
        }
    }
    for(auto& l: level){
        for(auto el: l.second){
            if(el.first > 0 and L[el.first-1][el.second] <= L[el.first][el.second]){
                unite(el, {el.first-1, el.second}, parent, children);
            }
            if(el.first < n-1 and L[el.first+1][el.second] <= L[el.first][el.second]){
                unite(el, {el.first+1, el.second}, parent, children);
            }
            if(el.second > 0 and L[el.first][el.second-1] <= L[el.first][el.second]){
                unite(el, {el.first, el.second-1}, parent, children);
            }
            if(el.second < m-1 and L[el.first][el.second+1] <= L[el.first][el.second]){
                unite(el, {el.first, el.second+1}, parent, children);
            }
            last = el;
        }
    }
    DFS(last, last, time, children, up, tin, tout);
    ++time;
    vector<ll> a(time);
    vector<ll> b(time);
    vector<ll> c(4*time);
    vector<Node> nodes(4*time);
    for(i=0;i<4*time;++i){
        c[i] = i;
    }
    for(i=0;i<n;++i){
        for(j=0;j<m;++j){
            a[tin[i][j]] = P[i][j];
        }
    }
    for(i=time-1;i>=0;--i){
        b[i] = *next[a[i]].begin();
        next[a[i]].insert(i);
        add(1, 0, time-1, i, b[i], 1, c, nodes);
    }
    for(i=0;i<q;++i){
        cin>>type;
        if(type == 2){
            cin>>x>>y>>val;
            swap(x, y);
            --x;
            --y;
            if(L[x][y] > val){
                cout<<0<<endl;
                continue;
            }
            auto p = get({x, y}, val, L, up);
            x = p.first;
            y = p.second;
            cout<<get(1, 0, time-1, tin[x][y], tout[x][y], tout[x][y], c, nodes)<<endl;
        }else{
            cin>>x>>y>>val;
            swap(x, y);
            --x;
            --y;
            pos = tin[x][y];
            add(1, 0, time-1, pos, b[pos], -1, c, nodes);
            auto it = next[a[pos]].find(pos);
            if(it != next[a[pos]].begin()){
                auto it2 = it;
                auto it3 = it;
                --it2;
                ++it3;
                add(1, 0, time-1, *it2, *it, -1, c, nodes);
                add(1, 0, time-1, *it2, *it3, 1, c, nodes);
                b[*it2] = *it3;
            }
            next[a[pos]].erase(it);
            a[pos] = val;
            next[a[pos]].insert(pos);
            next[a[pos]].insert(1e6);
            it = next[a[pos]].find(pos);
            if(it != next[a[pos]].begin()){
                auto it2 = it;
                auto it3 = it;
                --it2;
                ++it3;
                add(1, 0, time-1, *it2, *it, 1, c, nodes);
                add(1, 0, time-1, *it2, *it3, -1, c, nodes);
                b[*it2] = *it;
            }
            b[pos] = *(++it);
            add(1, 0, time-1, pos, b[pos], 1, c, nodes);
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    srand(time(nullptr));
    ll t=1;
//    cin>>t;
    for(;t>0;--t){
        solve();
    }
    return 0;
}
#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...