链接:点我
预处理:b[i][j]表示a[1] ... a[j]中比a[i]小的数的数量。
设
int get_lower_count(int b[], int l, int r)
{
return b[r] - b[l - 1];
}
枚举左端点i,右端点j,则 get_lower_count(b[j], i + 1, j) - get_lower_count(b[i], i,
j)为a[i]...a[j]的“顺序对的值”。因为a...a[j-1]中的值只有3种情况,要么比a[j]大,要么在a[i]与a[j]之间,要么比
a[i]小。比a[i]小的数,必然比a[j]小。所以用比a[j]小的数剪掉比a[i]小的数即可。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 typedef long long ll; 13 #define cl(a) memset(a,0,sizeof(a)) 14 #define ts printf("***** "); 15 const int MAXN=5005; 16 int n,m,tt,a[MAXN],f[MAXN][MAXN]; //1到j中比a[i]小的数 17 int main() 18 { 19 int i,j,k; 20 /*#ifndef ONLINE_JUDGE 21 freopen("1.in","r",stdin); 22 #endif*/ 23 scanf("%d",&n); 24 for(i=1;i<=n;i++) 25 { 26 scanf("%d",a+i); 27 } 28 cl(f); 29 for(i=1;i<=n;i++) 30 { 31 f[i][1]=(a[i]>a[1]); 32 for(j=2;j<=n;j++) 33 { 34 f[i][j]=f[i][j-1]+(a[j]<a[i]); 35 } 36 } 37 long long ans=0,ans1,ans2; 38 for(i=1;i<n;i++) 39 { 40 for(j=i+2;j<=n;j++) 41 { 42 if(a[j]>a[i]) 43 { 44 ans1=f[j][j]-f[j][i]; //i到j内比a[j]小的数(注意这里不包含i和j) 45 ans2=f[i][j]-f[i][i]; //i到j内比a[i]小的数 46 ans+=(ans1-ans2); 47 //printf("%d %d %d %d %d ",i,j,ans1,ans2,ans); 48 } 49 } 50 } 51 printf("%I64d ",ans); 52 }