1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| #pragma GCC optimize ("O3") #define DREP(i, s, e) for(int i = s; i >= e ;i--) #define REP(i, s, e) for(int i = s; i <= e ;i++)
#define DEBUG fprintf(stderr, "Passing [%s] in Line %d\n", __FUNCTION__, __LINE__) #define chkmax(a, b) a = max(a, b) #define chkmin(a, b) a = min(a, b)
#include <algorithm> #include <iostream> #include <cstdio>
using namespace std; const int maxn = 100000 + 10, maxm = 50000 + 10, inf = 1e9; template <typename T> inline T read() { T ans(0), p(1); char c = getchar(); while (!isdigit(c)) { if (c == '-') p = -1; c = getchar(); } while (isdigit(c)) { ans = ans * 10 + c - 48; c = getchar(); } return ans * p; }
int n, m, a[maxn], t[maxn], del[maxn], id[maxn], notin[maxn];
int cnt[maxn << 1], Min[maxn << 1], Max[maxn << 1], lp[maxn << 1], rp[maxn << 1]; #define mid (l + r >> 1) #define ls p << 1 #define rs p << 1 | 1 #define lson ls, l, mid - 1 #define rson rs, mid + 1, r inline bool cmp1(int a, int b) {return a < b;} inline bool cmp2(int a, int b) {return id[a] < id[b];} inline int Cmp1(const void *a, const void *b) {return (*(int*)a) - (*(int*)b);} inline int Cmp2(const void *a, const void *b) {return id[(*(int*)a)] - id[(*(int*)b)];} int pos[maxn]; #define pushup(p, l, r)\ {\ cnt[p] = (!notin[t[mid]]) + cnt[ls] + cnt[rs];\ Min[p] = min(notin[t[mid]] ? inf : t[mid], min(Min[ls], Min[rs]));\ Max[p] = max(notin[t[mid]] ? -inf : t[mid], max(Max[ls], Max[rs]));\ } void build(int p, int l, int r, bool flag = 0) { if (l > r) return; qsort(t + l, r - l + 1, 4, flag ? Cmp1 : Cmp2); pos[t[mid]] = mid; lp[p] = rp[p] = id[t[mid]]; build(lson, flag ^ 1); build(rson, flag ^ 1); cnt[p] = !notin[t[mid]]; Min[p] = notin[t[mid]] ? inf : t[mid]; Max[p] = notin[t[mid]] ? -inf : t[mid]; if (l < r) { pushup(p, l, r); chkmin(lp[p], min(lp[ls], lp[rs])); chkmax(rp[p], max(rp[ls], rp[rs])); } } int queryA(int p, int l, int r, int L, int R, int val) { if (l > r || L > rp[p] || R < lp[p] || Max[p] < val || !cnt[p]) return 0; bool flag(!notin[t[mid]] && L <= id[t[mid]] && id[t[mid]] <= R && t[mid] > val); if (L <= lp[p] && rp[p] <= R && Min[p] > val) return cnt[p]; else return queryA(lson, L, R, val) + queryA(rson, L, R, val) + flag; } int queryB(int p, int l, int r, int L, int R, int val) { if (l > r || L > rp[p] || R < lp[p] || Min[p] > val || !cnt[p]) return 0; bool flag(!notin[t[mid]] && L <= id[t[mid]] && id[t[mid]] <= R && t[mid] < val); if (L <= lp[p] && rp[p] <= R && Max[p] < val) return cnt[p]; else return queryB(lson, L, R, val) + queryB(rson, L, R, val) + flag; } void insert(int p, int l, int r, int pos) { cnt[p]++; chkmin(Min[p], t[pos]); chkmax(Max[p], t[pos]); if (mid == pos) return; else if (pos < mid) insert(lson, pos); else insert(rson, pos); } long long ans[maxm];
int main() { #ifdef CraZYali freopen("3157-new.in", "r", stdin); freopen("3157-new.out", "w", stdout); #endif cin >> n >> m; REP(i, 0, 200000) Max[i] = rp[i] = -inf, Min[i] = lp[i] = inf;
REP(i, 1, n) id[a[i] = read<int>()] = i; REP(i, 1, m) notin[del[i] = read<int>()] = 1; copy(a + 1, a + 1 + n, t + 1); build(1, 1, n); REP(i, 1, n) if (!notin[a[i]]) ans[m+1] += queryB(1, 1, n, i+1, n, a[i]); DREP(i, m, 1) { ans[i] = ans[i+1] + queryA(1, 1, n, 1, id[del[i]] - 1, del[i]) + queryB(1, 1, n, id[del[i]] + 1, n, del[i]); notin[del[i]] = 0; insert(1, 1, n, pos[del[i]]); } REP(i, 1, m) printf("%lld\n", ans[i]); return 0; }
|