嘛,好久没碰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 }
P3157

相关文章: