2016-06-22
这个题本想昨天晚上做来,但昨晚狂风大作,暴雨倾盆(听说我们学校最落后的一堵墙都被吹到了),停电了,我只能无聊的瞭望了教学楼一晚上。。。。。。
这个题把删除看成插入的话,插入一个点 新增逆序对就是比他早插入的,位置靠前,数比他大或 位置靠后,数比他小。那这就是个三维偏序集,可以用CDQ搞搞了。
这个题也能用树套树,树状数组归并排序做(以后有时间要写一写,恐怕是没可能了%>_<%)。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 #include<queue> 7 #define ll long long 8 #define M 1000009 9 using namespace std; 10 ll read() 11 { 12 char ch=getchar(); 13 ll x=0,f=1; 14 for(;ch<'0'||ch>'9';ch=getchar()) 15 if(ch=='-') 16 f=-1; 17 for(;ch>='0'&&ch<='9';ch=getchar()) 18 x=x*10+ch-'0'; 19 return x*f; 20 } 21 int n,m; 22 ll ans[M],shu[M]; 23 bool f[M]; 24 struct data 25 { 26 int A,B,C; 27 }a[M]; 28 bool cmp(data a1,data a2) 29 { 30 return a1.A>a2.A; 31 } 32 bool cmp1(data a1,data a2) 33 { 34 return a1.B<a2.B; 35 } 36 void jia(int x) 37 { 38 for(;x<=n;x+=x&-x) 39 shu[x]++; 40 } 41 void jian(int x) 42 { 43 for(;x<=n;x+=x&-x) 44 shu[x]--; 45 } 46 int query(int x) 47 { 48 int sum=0; 49 for(;x;x-=x&-x) 50 sum+=shu[x]; 51 return sum; 52 } 53 void cdq(int l,int r) 54 { 55 if(l==r) 56 return; 57 int mid=(l+r)>>1; 58 cdq(l,mid); 59 cdq(mid+1,r); 60 sort(a+l,a+mid+1,cmp1); 61 sort(a+mid+1,a+r+1,cmp1); 62 int l1=l,l2=mid+1; 63 for(;l1<=mid&&l2<=r;) 64 if(a[l1].B<a[l2].B) 65 { 66 jia(n-a[l1].C+1); 67 l1++; 68 } 69 else 70 { 71 ans[a[l2].A]+=query(n-a[l2].C+1); 72 l2++; 73 } 74 for(int i=l2;i<=r;i++) 75 ans[a[i].A]+=query(n-a[i].C+1); 76 for(int i=l;i<l1;i++) 77 jian(n-a[i].C+1); 78 } 79 int main() 80 { 81 n=read(); 82 m=read(); 83 for(int i=1;i<=n;i++) 84 { 85 int a1=read(); 86 a[a1].B=i; 87 a[a1].C=a1; 88 } 89 for(int i=1;i<=m;i++) 90 { 91 int a1=read(); 92 f[a1]=1; 93 a[a1].A=i; 94 } 95 int y=0; 96 for(int i=1;i<=n;i++) 97 if(!f[i]) 98 { 99 ++y; 100 a[i].A=m+y; 101 } 102 sort(a+1,a+n+1,cmp); 103 cdq(1,n); 104 for(int i=1;i<=n;i++) 105 { 106 a[i].B=n-a[i].B+1; 107 a[i].C=n-a[i].C+1; 108 } 109 sort(a+1,a+n+1,cmp); 110 cdq(1,n); 111 for(int i=n;i;i--) 112 ans[i]+=ans[i+1]; 113 for(int i=1;i<=m;i++) 114 printf("%lld ",ans[i]); 115 return 0; 116 }