Submission #12865

#TimeUsernameProblemLanguageResultExecution timeMemory
12865tncks0121Fortune Telling 2 (JOI14_fortune_telling2)C++14
100 / 100
444 ms46240 KiB
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <memory.h> #include <math.h> #include <assert.h> #include <stack> #include <queue> #include <map> #include <set> #include <algorithm> #include <string> #include <functional> #include <vector> #include <numeric> #include <deque> #include <utility> #include <bitset> #include <limits.h> #include <iostream> using namespace std; typedef long long ll; typedef unsigned long long llu; typedef double lf; typedef unsigned int uint; typedef long double llf; typedef pair<int, int> pii; const int N_ = 200500; const int K_ = 200500; const int LEAF = 131072*2; int N, K, A[N_], B[N_]; int T[K_], X[K_], XN; struct state { int s, b; state (int s = (int)1e8, int b = -(int)1e8): s(s), b(b) { } }; state tree[LEAF+LEAF]; state merged (state x, state y) { return state(min(x.s, y.s), max(x.b, y.b)); } void upd (int p, state v) { p += LEAF; tree[p] = merged(tree[p], v); while(p >>= 1) tree[p] = merged(tree[p+p], tree[p+p+1]); } state get (int x, int y) { state ret; if(x > y || x < 1 || y < 1 || x > XN || y > XN) return ret; x += LEAF; y += LEAF; while(x <= y) { if((x & 1) == 1) ret = merged(ret, tree[x]); if((y & 1) == 0) ret = merged(ret, tree[y]); x = (x+1) >> 1; y = (y-1) >> 1; } return ret; } ll ans; int cntX[N_]; vector<int> tree2[LEAF+LEAF]; int count2 (vector<int> &a, int v) { return (int)a.size() - (upper_bound(a.begin(), a.end(), v-1) - a.begin()); } int get2 (int x, int y, int v) { int ret = 0; x += LEAF; y += LEAF; while(x <= y) { if((x & 1) == 1) ret += count2 (tree2[x], v); if((y & 1) == 0) ret += count2 (tree2[y], v); x = (x + 1) >> 1; y = (y - 1) >> 1; } return ret; } int main() { scanf("%d%d", &N, &K); for(int i = 1; i <= N; i++) scanf("%d%d", A+i, B+i); for(int i = 1; i <= K; i++) scanf("%d", T+i), X[i] = T[i]; sort(X+1, X+K+1); XN = unique(X+1, X+K+1) - (X+1); for(int i = 1; i <= K; i++) { int x = lower_bound(X+1, X+XN+1, T[i]) - X; upd(x, state(i, i)); tree2[LEAF+i].push_back(x); ++cntX[x]; } for(int u = LEAF-1; u > 0; u--) { vector<int> &c1 = tree2[u+u]; vector<int> &c2 = tree2[u+u+1]; vector<int> &nd = tree2[u]; nd.reserve(c1.size() + c2.size()); for(int i = 0, j = 0; nd.size() < c1.size() + c2.size(); ) { if(i == c1.size()) nd.push_back(c2[j++]); else if(j == c2.size()) nd.push_back(c1[i++]); else if(c1[i] < c2[j]) nd.push_back(c1[i++]); else nd.push_back(c2[j++]); } } for(int i = 1; i <= XN; i++) cntX[i] += cntX[i-1]; for(int i = 1; i <= N; i++) { bool r = true; if(A[i] > B[i]) r = false, swap(A[i], B[i]); int a = upper_bound(X+1, X+XN+1, A[i]-1) - X; int b = upper_bound(X+1, X+XN+1, B[i]-1) - X; state p = get(a, b-1); // I state q = get(b, XN); // J int t; if(q.b == p.b + 1 && p.b > 0) { // .. -> p -> q t = A[i]; }else if(p.b > q.b && q.b > 0) { // q -> q -> q -> p t = B[i]; }else if(p.b - 1 > q.b && p.b > 0) { // .. -> p -> p t = B[i]; }else if(q.b > p.b && p.b > 0) { // .. -> p -> q -> q -> .. t = get2(p.b+1, K, b) % 2 == 1 ? A[i] : B[i]; }else { // only q t = r ^ ((K - cntX[a-1]) % 2 == 1) ? A[i] : B[i]; } if(K <= 10) { if(!r) swap(A[i], B[i]); } ans += t; } printf("%lld\n", ans); return 0; } /* 1 5 5 6 7 3 5 7 6 6 4 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...