luogu P1393 & P3157 动态逆序对

Posted yuyanjiab

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu P1393 & P3157 动态逆序对相关的知识,希望对你有一定的参考价值。

传送门

另一个在推荐的相关题目里有

删除不好删 反过来变成加 都是基本操作

然后被删的数加一维就是时间 

然后时间第一维 序号第二维 权值第三维

开一个权值树状数组维护三维偏序就行

两个题要注意输入的时候一个是删掉的权值 一个是删掉的编号

然后如果开不下要离散化

Code:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #define rep(i,a,n) for(int i = a;i <= n;++i)
 6 #define per(i,n,a) for(int i = n;i >= a;--i)
 7 using namespace std;
 8 typedef long long ll;
 9 ll read() {
10     ll as = 0,fu = 1;
11     char c = getchar();
12     while(c < 0 || c > 9) {
13         if(c == -) fu = -1;
14         c = getchar();
15     }
16     while(c >= 0 && c <= 9) {
17         as = as * 10 + c - 0;
18         c = getchar();
19     }
20     // printf("#%d
",as);
21     return as * fu;
22 }
23 const int N = 100005;
24 //head
25 int n,Q;
26 struct node {
27     int x,idx,tim;
28     bool operator < (const node &o) const {
29         return tim < o.tim || (tim == o.tim && idx < o.idx);
30     }
31 } a[N],tmp[N];
32 int b[N],ans[N];
33 
34 int t[N];
35 void upd(int x,int k) {
36     for(int i = x;i <= n;i += (i & (-i))) t[i] += k;
37 }
38 int qry(int x) {
39     int sum = 0;
40     for(int i = x;i;i -= (i & (-i))) sum += t[i];
41     return sum;
42 }
43 
44 
45 void CDQ(int l,int r) {
46     if(l == r) return;
47     int m = l+r >> 1,p1,p2;
48     CDQ(l,m),CDQ(m+1,r);
49 
50     p1 = l,p2 = m+1;
51     rep(i,l,r) {
52         if(p1 <= m && (p2 > r || a[p1].idx < a[p2].idx))
53             tmp[i] = a[p1],upd(a[p1].x,1),p1++;
54         else tmp[i] = a[p2],ans[tmp[i].tim] += qry(n) - qry(a[p2].x),p2++;
55     }
56     rep(i,l,m) upd(a[i].x,-1);
57 
58     p1 = m,p2 = r;
59     rep(i,l,r) {
60         if(p1 >= l && (p2 == m || (a[p1].idx > a[p2].idx)))
61             upd(a[p1].x,1),p1--;
62         else ans[a[p2].tim] += qry(a[p2].x-1),p2--;
63     }
64     rep(i,l,m) upd(a[i].x,-1);
65 
66     rep(i,l,r) a[i] = tmp[i];
67 }
68 
69 int main() {
70     n = read(),Q = read();
71     rep(i,1,n) {
72         a[i].x = read();
73         a[i].idx = b[a[i].x] = i;
74         a[i].tim = 1;
75     }
76     rep(i,1,Q) a[b[read()]].tim = n-i+1;
77     sort(a+1,a+n+1),CDQ(1,n);
78     int tot = 0;
79     rep(i,1,n) tot += ans[i];
80     per(i,n,n - Q + 1) printf("%lld
",tot),tot -= ans[i];
81     return 0;
82 }

 

以上是关于luogu P1393 & P3157 动态逆序对的主要内容,如果未能解决你的问题,请参考以下文章

[Luogu P3157][CQOI2011]动态逆序对 (树套树)

luogu P3157 [CQOI2011]动态逆序对(CDQ分治)

P3157 [CQOI2011]动态逆序对

P3157 动态逆序对 CDQ分治

洛谷 P3157 [CQOI2011]动态逆序对 | CDQ分治

P1393 动态逆序对