Submission #70371

# Submission time Handle Problem Language Result Execution time Memory
70371 2018-08-22T17:25:52 Z Benq Synchronization (JOI13_synchronization) C++14
100 / 100
2230 ms 140216 KB
#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
 
typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

const int MOD = 1000000007;
const ll INF = 1e18;
const int MX = 100001;

int N,M,Q, X[MX], Y[MX];
vi change[MX];

int numLE(vi& v, int x) { return distance(v.begin(),ub(all(v),x)); }

void merge(vi& a, vi& b) {
    if (sz(a) < sz(b)) swap(a,b);
    a.insert(a.end(),all(b));
}

void comb(map<int,vi>& a, map<int,vi>& b) {
    if (sz(a) < sz(b)) swap(a,b);
    for (auto& x: b) merge(a[x.f],x.s);
    b.clear();
}
    
template<int SZ> struct centroidDecomp {
    int sub[SZ], par[SZ];
    bool done[SZ];
    pi cen[SZ];
    vi fromCentroid[SZ]; // from (cen) to (vertex at time N)
    vi stor[SZ]; vector<vi> stor2[SZ]; // from (vertex at time 1) to cen
    vpi adj[SZ];
    
    // ACTUAL
    
    map<int,vi> fc[MX], tc[MX];
    
    void elimfc(map<int,vi>& m, int x) {
        for (int i = 0; i <= sz(change[x]); i += 2) {
            int l = (i > 0 ? change[x][i-1] : -MOD);
            int r = (i == sz(change[x]) ? MOD : change[x][i]-1);
            while (1) {
                auto it = m.ub(l);
                if (it != m.end() && it->f <= r) {
                    merge(m[l],it->s);
                    m.erase(it);
                } else break;
            }
        }
    }
    
    void elimtc(map<int,vi>& m, int x) {
        for (int i = 0; i <= sz(change[x]); i += 2) {
            int l = (i > 0 ? change[x][i-1]+1 : -MOD), r = (i == sz(change[x]) ? MOD : change[x][i]);
            while (1) {
                auto it = m.lb(l);
                if (it != m.end() && it->f < r) {
                    merge(m[r],it->s);
                    m.erase(it);
                } else break;
            }
        }
    }
    
    void gen(pi par, int no) {
        fc[no].clear(), tc[no].clear();
        fc[no][M].pb(no); tc[no][1].pb(no);
        
        for (auto i: adj[no]) if (!done[i.f] && i.f != par.f) {
            cen[i.f] = cen[no];
            gen({no,i.s},i.f);
            comb(fc[no],fc[i.f]); comb(tc[no],tc[i.f]);
        }
        
        elimfc(fc[no],par.s);
        elimtc(tc[no],par.s);
    }
    
    void doStuff(int x) {
        fromCentroid[x].pb(M); stor[x].pb(1);
        
        int co = 0;
        for (auto i: adj[x]) if (!done[i.f]) {
            cen[i.f] = {x,co};
            stor2[x].pb({});
            gen({x,i.s},i.f);
            for (auto a: fc[i.f]) for (auto b: a.s) {
                fromCentroid[b].pb(a.f);
                // cout << "AH " << x << " " << b << " " << a.f << "\n";
            }
            for (auto a: tc[i.f]) for (auto b: a.s) {
                stor[x].pb(a.f); 
                stor2[x][co].pb(a.f);
            }
            co ++;
        }
        /*cout << x << "\n";
        for (int i: stor[x]) cout << i << " ";
        exit(0);*/
        
        sort(all(stor[x])); F0R(i,co) sort(all(stor2[x][i]));
    }
        
    int query(int v) {
        int ret = 0;
        pi V; int ind; 
        for (V = {v,-1}, ind = sz(fromCentroid[v])-1; V.f; V = cen[V.f], ind --) {
            int d = fromCentroid[v][ind];
            // cout << "OOPS " << v << " " << V.f << " " << d << "\n";
            // cout << "OOPS " << d << "\n";
            
            ret += numLE(stor[V.f],d);
            if (V.s != -1) ret -= numLE(stor2[V.f][V.s],d);
        }
        return ret;
    }
    
    // centroid decomp
    
    void addEdge(int a, int b, int c) { adj[a].pb({b,c}), adj[b].pb({a,c}); }
    
    void dfs (int no) {
        sub[no] = 1;
        for (auto i: adj[no]) if (!done[i.f] && i.f != par[no]) {
            par[i.f] = no;
            dfs(i.f);
            sub[no] += sub[i.f];
        }
    }
    
    int getCentroid(int x) {
        par[x] = 0; dfs(x);
        int sz = sub[x];
        while (1) {
            pi mx = {0,0};
            for (auto i: adj[x]) if (!done[i.f] && i.f != par[x]) mx = max(mx,{sub[i.f],i.f});
            if (mx.f*2 > sz) x = mx.s;
            else return x;
        }
    }
    
    void solve (int x) {
        x = getCentroid(x); done[x] = 1;
        doStuff(x);
        for (auto i: adj[x]) if (!done[i.f]) solve(i.f);
    }
};

centroidDecomp<MX> cen;

void init() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    cin >> N >> M >> Q;
    FOR(i,1,N) {
        cin >> X[i] >> Y[i];
        cen.addEdge(X[i],Y[i],i);
    }
    FOR(i,1,M+1) {
        int D; cin >> D;
        change[D].pb(i);
    }
}

int main() {
    init();
    cen.solve(1);
    F0R(i,Q) {
        int C; cin >> C;
        cout << cen.query(C) << "\n";
    }
}

/* Look for:
* the exact constraints (multiple sets are too slow for n=10^6 :( ) 
* special cases (n=1?)
* overflow (ll vs int?)
* array bounds
* if you have no idea just guess the appropriate well-known algo instead of doing nothing :/
*/

Compilation message

synchronization.cpp: In instantiation of 'void centroidDecomp<SZ>::doStuff(int) [with int SZ = 100001]':
synchronization.cpp:182:16:   required from 'void centroidDecomp<SZ>::solve(int) [with int SZ = 100001]'
synchronization.cpp:204:16:   required from here
synchronization.cpp:129:45: warning: unused variable 'b' [-Wunused-variable]
             for (auto a: tc[i.f]) for (auto b: a.s) {
                                             ^
# Verdict Execution time Memory Grader output
1 Correct 30 ms 22232 KB Output is correct
2 Correct 26 ms 22256 KB Output is correct
3 Correct 28 ms 22308 KB Output is correct
4 Correct 26 ms 22440 KB Output is correct
5 Correct 24 ms 22552 KB Output is correct
6 Correct 35 ms 23176 KB Output is correct
7 Correct 166 ms 28288 KB Output is correct
8 Correct 144 ms 28444 KB Output is correct
9 Correct 180 ms 28748 KB Output is correct
10 Correct 1920 ms 83608 KB Output is correct
11 Correct 2041 ms 85980 KB Output is correct
12 Correct 1805 ms 94796 KB Output is correct
13 Correct 330 ms 94796 KB Output is correct
14 Correct 1753 ms 94796 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1110 ms 94796 KB Output is correct
2 Correct 1187 ms 94796 KB Output is correct
3 Correct 1886 ms 103608 KB Output is correct
4 Correct 2094 ms 105504 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 28 ms 105504 KB Output is correct
2 Correct 26 ms 105504 KB Output is correct
3 Correct 27 ms 105504 KB Output is correct
4 Correct 26 ms 105504 KB Output is correct
5 Correct 23 ms 105504 KB Output is correct
6 Correct 36 ms 105504 KB Output is correct
7 Correct 156 ms 105504 KB Output is correct
8 Correct 1941 ms 109304 KB Output is correct
9 Correct 1890 ms 112204 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1987 ms 115292 KB Output is correct
2 Correct 2074 ms 117032 KB Output is correct
3 Correct 2098 ms 119568 KB Output is correct
4 Correct 2094 ms 121848 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 25 ms 121848 KB Output is correct
2 Correct 25 ms 121848 KB Output is correct
3 Correct 27 ms 121848 KB Output is correct
4 Correct 26 ms 121848 KB Output is correct
5 Correct 35 ms 121848 KB Output is correct
6 Correct 151 ms 121848 KB Output is correct
7 Correct 2125 ms 121848 KB Output is correct
8 Correct 1850 ms 127944 KB Output is correct
9 Correct 302 ms 127944 KB Output is correct
10 Correct 2230 ms 127944 KB Output is correct
11 Correct 1231 ms 127944 KB Output is correct
12 Correct 1148 ms 129012 KB Output is correct
13 Correct 2041 ms 140216 KB Output is correct