洛谷 P1393 P3157 动态逆序对
嘛,好久没碰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 }
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 const int N = 40010; 6 7 int x[N], a[N], n; 8 9 struct TreeArray { 10 int tr[N]; 11 inline void clear() { 12 memset(tr, 0, sizeof(tr)); 13 return; 14 } 15 inline void add(int x, int a) { 16 for(; x < N; x += x & (-x)) { 17 tr[x] += a; 18 } 19 return; 20 } 21 inline int getsum(int x) { 22 int ans = 0; 23 for(; x; x -= x & (-x)) { 24 ans += tr[x]; 25 } 26 return ans; 27 } 28 inline int ask(int l, int r) { 29 if(l == 1) { 30 return getsum(r); 31 } 32 return getsum(r) - getsum(l - 1); 33 } 34 }ta; 35 36 struct Node { 37 int val, ans, time, type, id; 38 }node[N], temp[N]; 39 40 inline bool cmp_t(Node d, Node e) { 41 return d.time < e.time; 42 } 43 inline bool cmp__t(Node d, Node e) { 44 return d.time > e.time; 45 } 46 47 void CDQ1(int l, int r) { 48 if(l == r) { 49 return; 50 } 51 int mid = (l + r) >> 1; 52 CDQ1(l, mid); 53 CDQ1(mid + 1, r); 54 55 int i = l, j = mid + 1, t = 0; 56 while(i <= mid || j <= r) { 57 if(j > r || (i <= mid && node[i].id < node[j].id)) { 58 ta.add(node[i].val, 1); 59 temp[++t] = node[i++]; 60 } 61 else { 62 if(node[j].type == 2) { 63 node[j].ans += ta.ask(node[j].val + 1, n); 64 } 65 temp[++t] = node[j++]; 66 } 67 } 68 for(i = l; i <= mid; i++) { 69 ta.add(node[i].val, -1); 70 } 71 t = 0; 72 for(int i = l; i <= r; i++) { 73 node[i] = temp[++t]; 74 } 75 return; 76 } 77 78 void CDQ2(int l, int r) { 79 if(l == r) { 80 return; 81 } 82 int mid = (l + r) >> 1; 83 CDQ2(l, mid); 84 CDQ2(mid + 1, r); 85 86 int i = l, j = mid + 1, t = 0; 87 while(i <= mid || j <= r) { 88 if(j > r || (i <= mid && node[i].id > node[j].id)) { 89 ta.add(node[i].val, 1); 90 temp[++t] = node[i++]; 91 } 92 else { 93 if(node[j].type == 2) { 94 node[j].ans += ta.getsum(node[j].val - 1); 95 } 96 temp[++t] = node[j++]; 97 } 98 } 99 for(i = l; i <= mid; i++) { 100 ta.add(node[i].val, -1); 101 } 102 t = 0; 103 for(i = l; i <= r; i++) { 104 node[i] = temp[++t]; 105 } 106 return; 107 } 108 109 int main() { 110 int m; 111 scanf("%d%d", &n, &m); 112 for(int i = 1; i <= n; i++) { 113 scanf("%d", &a[i]); 114 x[i] = a[i]; 115 node[i].id = i; 116 node[i].type = 1; /// normal 117 } 118 std::sort(x + 1, x + n + 1); 119 int xx = std::unique(x + 1, x + n + 1) - x - 1; 120 for(int i = 1; i <= n; i++) { 121 int p = std::lower_bound(x + 1, x + xx + 1, a[i]) - x; 122 node[i].val = p; 123 } 124 /// li san hua wan bi 125 126 int nn = n; 127 for(int i = 1; i <= m; i++) { 128 scanf("%d", &xx); 129 node[xx].type = 2; /// add 130 node[xx].time = nn--; 131 } 132 for(int i = 1; i <= n; i++) { 133 if(node[i].type == 1) { 134 node[i].time = nn--; 135 } 136 } 137 int ans = 0; 138 for(int i = 1; i <= n; i++) { 139 if(node[i].type == 1) { 140 ans += ta.ask(node[i].val + 1, n); 141 ta.add(node[i].val, 1); 142 } 143 } 144 ta.clear(); 145 std::sort(node + 1, node + n + 1, cmp_t); 146 CDQ1(1, n); 147 std::sort(node + 1, node + n + 1, cmp_t); 148 CDQ2(1, n); 149 std::sort(node + 1, node + n + 1, cmp__t); 150 for(int i = 1; i <= m; i++) { 151 ans += node[i].ans; 152 } 153 for(int i = 1; i <= m + 1; i++) { 154 printf("%d ", ans); 155 ans -= node[i].ans; 156 } 157 return 0; 158 }
CDQ大法好!