This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |