嘛,好久没碰CDQ分治了,做道题练练手。
时间倒流——把删数改为加数。
对于每个被删的,我的想法是拆成询问和add,后来发现一个足矣。
我本来准备对每个删的数都求一遍整体逆序对,后来发现无论如何都不可做。
然后发现是只求改的逆序对,做两次CDQ,一次统计在前面大的,一次统计在后面小的。
注意:这两次的区别是id那一维的顺序不同,而time顺序是相同的。
记得离散化。
然后我打完 + 静态差错之后,一发过样例AC,稳!!!
顺手切了一模一样的3157,WA了两个点。发现输出负数......换成longlong之后AC。
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 typedef long long LL; 6 7 const LL N = 100010; 8 9 LL x[N], a[N], n; 10 11 struct TreeArray { 12 LL tr[N]; 13 inline void clear() { 14 memset(tr, 0, sizeof(tr)); 15 return; 16 } 17 inline void add(LL x, LL a) { 18 for(; x < N; x += x & (-x)) { 19 tr[x] += a; 20 } 21 return; 22 } 23 inline LL getsum(LL x) { 24 LL ans = 0; 25 for(; x; x -= x & (-x)) { 26 ans += tr[x]; 27 } 28 return ans; 29 } 30 inline LL ask(LL l, LL r) { 31 if(l == 1) { 32 return getsum(r); 33 } 34 return getsum(r) - getsum(l - 1); 35 } 36 }ta; 37 38 struct Node { 39 LL val, ans, time, type, id; 40 }node[N], temp[N]; 41 42 inline bool cmp_t(Node d, Node e) { 43 return d.time < e.time; 44 } 45 inline bool cmp__t(Node d, Node e) { 46 return d.time > e.time; 47 } 48 49 void CDQ1(LL l, LL r) { 50 if(l == r) { 51 return; 52 } 53 LL mid = (l + r) >> 1; 54 CDQ1(l, mid); 55 CDQ1(mid + 1, r); 56 57 LL i = l, j = mid + 1, t = 0; 58 while(i <= mid || j <= r) { 59 if(j > r || (i <= mid && node[i].id < node[j].id)) { 60 ta.add(node[i].val, 1); 61 temp[++t] = node[i++]; 62 } 63 else { 64 if(node[j].type == 2) { 65 node[j].ans += ta.ask(node[j].val + 1, n); 66 } 67 temp[++t] = node[j++]; 68 } 69 } 70 for(i = l; i <= mid; i++) { 71 ta.add(node[i].val, -1); 72 } 73 t = 0; 74 for(LL i = l; i <= r; i++) { 75 node[i] = temp[++t]; 76 } 77 return; 78 } 79 80 void CDQ2(LL l, LL r) { 81 if(l == r) { 82 return; 83 } 84 LL mid = (l + r) >> 1; 85 CDQ2(l, mid); 86 CDQ2(mid + 1, r); 87 88 LL i = l, j = mid + 1, t = 0; 89 while(i <= mid || j <= r) { 90 if(j > r || (i <= mid && node[i].id > node[j].id)) { /// error : id < id 91 ta.add(node[i].val, 1);/// error : if(type == 1) 92 temp[++t] = node[i++]; 93 } 94 else { 95 if(node[j].type == 2) { 96 node[j].ans += ta.getsum(node[j].val - 1); 97 } 98 temp[++t] = node[j++]; 99 } 100 } 101 for(i = l; i <= mid; i++) { 102 ta.add(node[i].val, -1);/// error : if(type == 1) 103 } 104 t = 0; 105 for(i = l; i <= r; i++) { 106 node[i] = temp[++t]; 107 } 108 return; 109 } 110 111 LL pos[N]; 112 113 int main() { 114 LL m; 115 scanf("%lld%lld", &n, &m); 116 for(LL i = 1; i <= n; i++) { 117 scanf("%lld", &a[i]); 118 x[i] = a[i]; 119 node[i].id = i; 120 node[i].type = 1; /// normal 121 } 122 std::sort(x + 1, x + n + 1); 123 LL xx = std::unique(x + 1, x + n + 1) - x - 1; 124 for(LL i = 1; i <= n; i++) { 125 LL p = std::lower_bound(x + 1, x + xx + 1, a[i]) - x; 126 node[i].val = p; 127 pos[p] = i; 128 } 129 /// li san hua wan bi 130 131 LL nn = n, p; 132 for(LL i = 1; i <= m; i++) { 133 scanf("%lld", &p); 134 p = std::lower_bound(x + 1, x + xx + 1, p) - x; 135 p = pos[p]; 136 node[p].type = 2; /// add 137 node[p].time = nn--; 138 } 139 for(LL i = 1; i <= n; i++) { 140 if(node[i].type == 1) { 141 node[i].time = nn--; 142 } 143 } 144 LL ans = 0; 145 for(LL i = 1; i <= n; i++) { 146 if(node[i].type == 1) { 147 ans += ta.ask(node[i].val + 1, n); 148 ta.add(node[i].val, 1); 149 } 150 } 151 ta.clear(); 152 std::sort(node + 1, node + n + 1, cmp_t); 153 CDQ1(1, n); 154 std::sort(node + 1, node + n + 1, cmp_t); /// error : cmp__t -> cmp_t 155 CDQ2(1, n); 156 std::sort(node + 1, node + n + 1, cmp__t); 157 for(LL i = 1; i <= m; i++) { 158 ans += node[i].ans; 159 } 160 for(LL i = 1; i <= m; i++) { 161 printf("%lld\n", ans); 162 ans -= node[i].ans; 163 } 164 return 0; 165 }