题意即求在区间$[l,r]$中且权值在$[x,y]$中的逆序对个数
考虑分块,逆序对个数包含4部分:
1.左/右块外内部,预处理出$i$到其所在块的块首/尾,小于/小于等于$j$(需要对$j$离散)的数即可;
2.左块外与右块外,预处理出每个块内数的顺序,来对左/右块外排序,再归并排序即可;
3.左/右块外到块内,预处理出前$i$个块中小于/小于等于$j$的数个数;
4.块内部,对权值区间$[x,y]$容斥,变为$[1,y]-[1,x)-[1,x)与[x,y]$
$[1,y]$和$[1,x)$类似,预处理第$i$个块中的$j$(离散)在 第$k$个块中比其小的数的个数,特别的,当$k=i$定义为$i$到其所在块块首小于$j$的数个数(即1.),然后对$j$和$k$两维求前缀和即可(预处理过程中,为了避免二分,可以先枚举$k$再枚举$j$)
$[1,x)$与$[x,y]$,答案分为两类:1.块与块之间;2.块内部
第1个比较好做,枚举前$i$个块,即求出前$i-1$个块中$[1,x)$的点个数*第$i$个块中$[x,y]$的点个数,用3.的预处理即可
第2个对第$i$个块预处理出$j$是否在$k$之前(离散),那么即求$sum_{j=1}^{x-1}sum_{k=x}^{y}f[j][k]$,二位前缀和来计算即可
特别的,当$l$和$r$在同一个连通块中,直接用第1种做法,再对询问区间容斥一下即可
时间复杂度为$o(nsqrt{n})$,常数极大,可能无法通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define K 300 5 #define NdK 400 6 vector<int>v,vl,vr; 7 int n,m,l,r,x,y,a[N],b[N],bl[N],st[N],ed[N],id[N]; 8 int g1[N][K+10],g2[N][K+10],g3[NdK][N],g4[NdK][N],f1[NdK][K+10][NdK],f2[NdK][K+10][K+10]; 9 long long ans; 10 int calc1(int k){//统计[st[bl[k]],k]范围内的答案 11 int z=g3[bl[k]][x]-g3[bl[k]-1][x],ans=0; 12 for(int i=st[bl[k]];i<=k;i++)//xx<=id[x]<id[i] 13 if ((x<=a[i])&&(a[i]<=y))ans+=g1[i][id[i]]-g1[i][z]; 14 return ans; 15 } 16 int calc2(int k){//统计[k,ed[bl[k]]范围内的答案 17 int z=g4[bl[k]][y]-g4[bl[k]-1][y]-1,ans=0; 18 for(int i=k;i<=ed[bl[k]];i++)//id[i]<id[x]<=y 19 if ((x<=a[i])&&(a[i]<=y))ans+=g2[i][z]-g2[i][id[i]]; 20 return ans; 21 } 22 int calc3(int l,int r){//统计[l,r]范围内的答案 23 int z=g3[bl[l]][x]-g3[bl[l]-1][x],ans=0; 24 for(int i=l;i<=r;i++)//id[i]<id[x]<=yy,l<=x<=i 25 if ((x<=a[i])&&(a[i]<=y))ans+=g1[i][id[i]]-g1[i][z]-g1[l-1][id[i]]+g1[l-1][z]; 26 return ans; 27 } 28 long long calc4(int l,int r,int x){//统计[bl[l],ed[r]],[1,x]的答案 29 int ans=0; 30 for(int i=l;i<=r;i++){ 31 int y=g4[i][x]-g4[i-1][x]-1; 32 if (y>=0)ans+=f1[i][y][i]-f1[i][y][l-1]; 33 } 34 return ans; 35 } 36 int merge(int x1,int y1,int x2,int y2){//归并排序[x1,y1]和[x2,y2]并统计答案 37 vl.clear(); 38 vr.clear(); 39 for(int i=x1;i<=y1;i++) 40 if ((x<=a[i])&&(a[i]<=y))b[id[i]]=a[i]; 41 for(int i=0;i<=ed[bl[x1]]-st[bl[x1]];i++) 42 if (b[i]){ 43 vl.push_back(b[i]); 44 b[i]=0; 45 } 46 for(int i=x2;i<=y2;i++) 47 if ((x<=a[i])&&(a[i]<=y))b[id[i]]=a[i]; 48 for(int i=0;i<=ed[bl[x2]]-st[bl[x2]];i++) 49 if (b[i]){ 50 vr.push_back(b[i]); 51 b[i]=0; 52 } 53 int ans=0; 54 for(int i=0,j=0,k=0;(i<vl.size())||(j<vr.size());k++) 55 if ((i<vl.size())&&((j==vr.size())||(vl[i]<vr[j])))i++; 56 else{ 57 j++; 58 ans+=k--; 59 } 60 return ans; 61 } 62 int main(){ 63 freopen("tears.in","r",stdin); 64 freopen("tears.out","w",stdout); 65 scanf("%d%d",&n,&m); 66 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 67 for(int i=1;i<=n;i++){ 68 bl[i]=i/K+1; 69 if (K==1)bl[i]--; 70 if (!st[bl[i]])st[bl[i]]=i; 71 ed[bl[i]]=i; 72 } 73 for(int i=1;i<=bl[n];i++){ 74 v.clear(); 75 for(int j=st[i];j<=ed[i];j++)v.push_back(a[j]); 76 sort(v.begin(),v.end()); 77 for(int j=st[i];j<=ed[i];j++)id[j]=lower_bound(v.begin(),v.end(),a[j])-v.begin(); 78 for(int j=0;j<=ed[i]-bl[i];j++){ 79 g1[st[i]][j]=(a[st[i]]<v[j]); 80 for(int k=st[i]+1;k<=ed[i];k++)g1[k][j]=g1[k-1][j]+(a[k]<v[j]); 81 g2[ed[i]][j]=(a[ed[i]]<=v[j]); 82 for(int k=ed[i]-1;k>=st[i];k--)g2[k][j]=g2[k+1][j]+(a[k]<=v[j]); 83 } 84 for(int j=1,k=0;j<=n;j++){ 85 while ((k<v.size())&&(v[k]<j))k++; 86 g3[i][j]=g3[i-1][j]+k; 87 g4[i][j]=g4[i-1][j]+k; 88 if ((k<v.size())&&(v[k]==j))g4[i][j]++; 89 } 90 for(int j=1;j<i;j++){ 91 f1[i][0][j]=g3[j][v[0]]-g3[j-1][v[0]]; 92 for(int k=1;k<v.size();k++)f1[i][k][j]=f1[i][k-1][j]+g3[j][v[k]]; 93 for(int k=0;k<v.size();k++)f1[i][k][j]+=f1[i][k][j-1]; 94 } 95 for(int j=st[i];j<=ed[i];j++)f1[i][id[j]][i]=g1[j][id[j]]; 96 for(int j=1;j<=ed[i]-st[i];j++)f1[i][j][i]+=f1[i][j-1][i]; 97 for(int j=0;j<=ed[i]-st[i];j++)f1[i][j][i]+=f1[i][j][i-1]; 98 for(int j=st[i];j<=ed[i];j++) 99 for(int k=j+1;k<=ed[i];k++) 100 if (a[j]<a[k])f2[i][id[j]][id[k]]=1; 101 for(int j=1;j<=ed[i]-st[i];j++){ 102 f2[i][j][0]+=f2[i][j-1][0]; 103 f2[i][0][j]+=f2[i][0][j-1]; 104 } 105 for(int j=1;j<=ed[i]-st[i];j++) 106 for(int k=1;k<=ed[i]-st[i];k++)f2[i][j][k]+=f2[i][j-1][k]+f2[i][j][k-1]-f2[i][j-1][k-1]; 107 } 108 for(int i=1;i<=m;i++){ 109 scanf("%d%d%d%d",&l,&r,&x,&y); 110 if (bl[l]==bl[r]){ 111 printf("%d ",calc3(l,r)); 112 continue; 113 } 114 ans=calc1(r)+calc2(l)+merge(l,ed[bl[l]],st[bl[r]],r); 115 for(int j=st[bl[r]];j<=r;j++)//x<=a[x]<a[j] 116 if ((x<=a[j])&&(a[j]<=y))ans+=g3[bl[r]-1][a[j]]-g3[bl[r]-1][x]-g3[bl[l]][a[j]]+g3[bl[l]][x]; 117 for(int j=l;j<=ed[bl[l]];j++)//a[j]<a[x]<=y 118 if ((x<=a[j])&&(a[j]<=y))ans+=g4[bl[r]-1][y]-g4[bl[r]-1][a[j]]-g4[bl[l]][y]+g4[bl[l]][a[j]]; 119 l=bl[l]+1; 120 r=bl[r]-1; 121 if (l<=r){ 122 ans+=calc4(l,r,y)-calc4(l,r,x-1); 123 for(int j=l;j<=r;j++)ans-=(g3[j-1][x]-g3[l-1][x])*(g4[j][y]-g3[j][x]-g4[j-1][y]+g3[j-1][x]); 124 for(int j=l;j<=r;j++){ 125 int xx=g3[j][x]-g3[j-1][x],yy=g4[j][y]-g4[j-1][y]-1; 126 ans-=f2[j][xx-1][yy]-f2[j][xx-1][xx-1]; 127 } 128 } 129 printf("%lld ",ans); 130 } 131 }