Submission #1269396

#TimeUsernameProblemLanguageResultExecution timeMemory
1269396thieunguyenhuyFortune Telling 2 (JOI14_fortune_telling2)C++20
0 / 100
1 ms320 KiB
#include <bits/stdc++.h>
using namespace std;

#define POPCOUNT(n) (__builtin_popcountll((n)))
#define CLZ(n) (__builtin_clzll((n)))
#define CTZ(n) (__builtin_ctzll((n)))
#define LOG(n) (63 - __builtin_clzll((n)))
#define BIT(n, i) (((n) >> (i)) & 1ll)
#define MASK(i) (1ll << (i))
#define FLIP(n, i) ((n) ^ (1ll << (i)))
#define ON(n, i) ((n) | MASK(i))
#define OFF(n, i) ((n) & ~MASK(i))

#define Int __int128
#define fi first
#define se second

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef pair<long long, int> pli;
typedef pair<int, long long> pil;
typedef vector<pair<int, int>> vii;
typedef vector<pair<long long, long long>> vll;
typedef vector<pair<long long, int>> vli;
typedef vector<pair<int, long long>> vil;

template <class T1, class T2> bool maximize(T1 &x, T2 y) {
    if (x < y) {
        x = y;
        return true;
    }
    return false;
}
template <class T1, class T2> bool minimize(T1 &x, T2 y) {
    if (x > y) {
        x = y;
        return true;
    }
    return false;
}

template <class T> void remove_duplicate(vector<T> &ve) {
    sort (ve.begin(), ve.end());
    ve.resize(unique(ve.begin(), ve.end()) - ve.begin());
}

mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
long long random(long long l, long long r) {
    return uniform_int_distribution<long long>(l, r)(rng);
}
unsigned long long random(unsigned long long l, unsigned long long r) {
    return uniform_int_distribution<unsigned long long>(l, r)(rng);
}
template <class T> T random(T r) {
    return rng() % r;
}

const int N = 1e6 + 5;
const int MOD = 1e9 + 7;
const int inf = 1e9;
const long long INF = 1e18;

int n, k;
int a[N], b[N], A[N], B[N], t[N], last[N], res[N];

struct FenwickTree {
    using T = int;
    vector<T> bit;

    FenwickTree() {}

    void resize(int n) {
        bit.assign(n + 1, 0);
    }

    void update(int p, T val) {
    	// cerr << "update " << p << ' ' << val << '\n';
        for (; p < int(bit.size()); p += p & -p) bit[p] += val;
    }

    T get(int p) {
        T ans = 0;
        for (; p > 0; p -= p & -p) ans += bit[p];
        return ans;
    }

    T get_max(int p) {
    	T ans = 0;
    	for (; p > 0; p -= p & -p) maximize(ans, bit[p]);
    	return ans;
    }
} fen;

signed main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

    cin >> n >> k;

    for (int i = 1; i <= n; ++i) {
    	cin >> a[i] >> b[i];
    	A[i] = a[i], B[i] = b[i];
    	if (A[i] > B[i]) swap(A[i], B[i]);
    }
    for (int i = 1; i <= k; ++i) cin >> t[i];

    reverse(t + 1, t + 1 + k);

    vector<int> order1(n); iota(order1.begin(), order1.end(), 1);
	sort (order1.begin(), order1.end(), [&](int x, int y) {
		return B[x] < B[y];
	});

    vector<int> order2(k); iota(order2.begin(), order2.end(), 1);
	sort (order2.begin(), order2.end(), [&](int x, int y) {
		return t[x] < t[y];
	});

	// cerr << "PHTN\n";

	fen.resize(k);
	for (int i = 0, j = -1; i < n; ++i) {
		// cerr << "i = " << i << ' ' << j << '\n';
		while (j + 1 < k && t[order2[j + 1]] < B[order1[i]]) {
			// cerr << order2[j + 1] << '\n';
			fen.update(order2[j + 1], t[order2[j + 1]]);
			++j;
		}


		int low = 1, high = k; last[order1[i]] = k + 1;
		while (low <= high) {
			int mid = (low + high) >> 1;
			if (fen.get_max(mid) >= A[order1[i]]) high = (last[order1[i]] = mid) - 1;
			else low = mid + 1;
		}
	}

	// cerr << "Nguyen\n";

	fen.resize(k);
	for (int i = n - 1, j = k; i >= 0; --i) {
		while (j > 0 && t[order2[j - 1]] >= B[order1[i]]) {
			fen.update(order2[j - 1], 1);
			--j;
		}
		int tmp = fen.get(last[order1[i]] - 1);
		if (last[order1[i]] == k + 1) res[order1[i]] = (tmp & 1 ? b[order1[i]] : a[order1[i]]);
		else res[order1[i]] = (tmp & 1 ? A[order1[i]] : B[order1[i]]);
	}

	// for (int i = 1; i <= n; ++i) cerr << res[i] << ' ';
	// cerr << '\n';

	// // Brute force
	// for (int i = k; i > 0; --i) {
	// 	for (int j = 1; j <= n; ++j) if (a[j] <= t[i]) {
	// 		swap(a[j], b[j]);
	// 	}
	// }
	// for (int i = 1; i <= n; ++i) cerr << a[i] << ' ';
	// cerr << '\n';

	ll ans = 0;
	for (int i = 1; i <= n; ++i) ans += res[i];
	cout << ans;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...