hust 1433(树状数组)
用两遍树状数组,分别求出a[i]与前面的数字组成的逆序对数记为c[i],
和与后面的数字组成的逆序对数记为d[i],以及总的逆序对数记为tot,
则
#include <cstdio>
#include <iostream>
const long long max_n = 100010;
long long a[max_n], c[max_n];
long long b[max_n];
long long lowbit(long long x)
{
return x & -x;
}
void insert(long long x, long long n)
{
for (; x <= n; x += lowbit(x))
c[x]++;
}
long long sum(long long x)
{
long long s = 0;
for (; x; x -= lowbit(x))
s += c[x];
return s;
}
void solve(long long n)
{
for (long long i = 1; i <= n; i++)
scanf("%lld", &a [i]);
memset(c, 0, sizeof (c));
b[n + 1] = 0;
for (long long i = n; i ; i--)
{
b[i] = sum(a[i]) + b[i + 1];
insert(a[i], n);
}
long long total = b[1], before = 0;
memset(c, 0, sizeof (c));
for (long long i = 1; i < n; i++)
{
before += i - 1 - sum(a[i]);
insert(a[i], n);
b[i] = total - before - b[i + 1];
}
for (int i = 1; i < n - 1; i++)
printf("%lld ", b[i]);
printf("%lld\n", b[n - 1]);
}
int main()
{
long long n;
while (scanf("%lld", &n) != EOF)
{
solve(n);
}
}方法二:#include<iostream>#include<cstdio>
#include<cstring>
using namespace std;
#define max 500001
long long tree[max];
long long x[max];
long long b[max];
long long getsum(long long idx)
{
long long sum=0;
while(idx>0)
{
sum+=tree[idx];
idx-=(idx&-idx);
}
return sum;
}
void add(long long idx)
{
while(idx<=max)
{
tree[idx]+=1;
idx+=(idx&-idx);
}
}
int main()
{
long long n,i;
while(scanf("%lld",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf("%lld",&x[i]);
b[i]=b[i-1]-(i-1-getsum(x[i]));
add(x[i]);
b[i]+=x[i]-getsum(x[i]);
}
for(i=1;i<n;i++)
{
if(i==1) printf("%lld",b[i]);
else printf(" %lld" ,b[i]);
}
printf("\n");
}
}方法三:#include<stdio.h>
#define MAXN 100010
long long a[MAXN],b[MAXN];
int main()
{
long long i,n;
while(scanf("%lld",&n)!=EOF)
{
b[0]=0;
for(i=1;i<=n;i++) scanf("%lld",&a[i]);
for(i=1;i<n;i++) b[i]=b[i-1]+a[i]-i;
for(i=1;i<n-1;i++) printf("%lld ",b[i]);
printf("%lld\n",b[i]);
}
return 0;
}
posted on 2011-06-05 16:01 thinking001 阅读(119) 评论(0) 收藏 举报

浙公网安备 33010602011771号