洛谷 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 }
P3157
  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 }
P1393

CDQ大法好!

posted @ 2018-07-13 21:16  huyufeifei  阅读(561)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜