bzoj 3295 动态逆序对
题目大意:
对于序列A,它的逆序对数定义为满足i<j,且Ai>Aj的数对(i,j)的个数。给1到n的一个排列,按照某种顺序依次删除m个元素,你的任务是在每次删除一个元素之前统计整个序列的逆序对数
思路:
转化一下的三位偏序
下标的倒序定为x 数值定为y 删除的倒序为z
然后对于每个元素需要求三个都比它大的,或z小,x y 都比它大的
最后求一下前缀和,输出答案
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 100100 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 int n,m,c[MAXN],hsh[MAXN]; 21 ll s[MAXN],ans[MAXN]; 22 struct data {int x,y,z,pos;}g[MAXN]; 23 bool cmp1(data a,data b) {return a.x<b.x;} 24 bool cmp2(data a,data b) {return a.y<b.y;} 25 bool cmp3(data a,data b) {return a.z<b.z;} 26 int lowbit(int x) {return x&(-x);} 27 void add(int x,int val) {for(int i=x;i<=n;i+=lowbit(i)) c[i]+=val;} 28 int query(int x) {int res=0;for(int i=x;i;i-=lowbit(i)) res+=c[i];return res;} 29 void cdq(int l,int r) 30 { 31 if(l==r) return ; 32 int mid=(l+r)>>1; 33 data m=g[mid]; 34 cdq(l,mid);cdq(mid+1,r); 35 sort(g+l,g+r+1,cmp2); 36 for(int i=l;i<=r;i++) 37 { 38 if(g[i].pos<=m.pos) add(g[i].z,1); 39 else ans[g[i].pos]+=query(g[i].z); 40 } 41 for(int i=l;i<=r;i++) if(g[i].pos<=m.pos) add(g[i].z,-1); 42 for(int i=r;i>=l;i--) 43 { 44 if(g[i].pos>m.pos) add(g[i].z,1); 45 else ans[g[i].pos]+=query(g[i].z); 46 } 47 for(int i=r;i>=l;i--) if(g[i].pos>m.pos) add(g[i].z,-1); 48 return ; 49 } 50 int main() 51 { 52 n=read(),m=read();int x; 53 for(int i=1;i<=n;i++) 54 g[i].x=n-i+1,g[i].y=read(),hsh[g[i].y]=i; 55 int k=n; 56 for(int i=1;i<=m;i++) 57 x=read(),g[hsh[x]].z=k--; 58 for(int i=1;i<=n;i++) if(!g[i].z) g[i].z=k--; 59 sort(g+1,g+n+1,cmp1); 60 for(int i=1;i<=n;i++) g[i].pos=i; 61 cdq(1,n); 62 sort(g+1,g+n+1,cmp3); 63 int res=0; 64 for(int i=1;i<=n;i++) s[i]=s[i-1]+ans[g[i].pos]; 65 for(int i=n;i>=n-m+1;i--) printf("%lld\n",s[i]); 66 }
Orz 一开始没开 long long 而且写了两个cdq在luogu上TLE了
然后优化到一个cdq里写才过
但是并不会直接写一个 棒棒太强啦