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)    收藏  举报

导航