| Time Limit: 7000MS | Memory Limit: 65536K | |
| Total Submissions: 32606 | Accepted: 11633 |
Description
In this problem, you have to analyze a particular sortingalgorithm. The algorithm processes a sequence of n distinctintegers by swapping two adjacent sequence elements until thesequence is sorted in ascending order. For the inputsequence
Ultra-QuickSort produces the output
Your task is to determine how many swap operations Ultra-QuickSortneeds to perform in order to sort a given input sequence.
Input
Output
Sample Input
5 9 1 0 5 4 3 1 2 3 0
Sample Output
6 0
1.设每个数二进制末尾0的个数是k,则每个数管的数个数就是2的k次方,并且管的最后一个就是自己那个数。比如8的2进制是1000,有3个0,2的3次方是8,则c[8]=a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8]=a[4]+a[6]+a[7]+a[8]。所以用这种方法求和的话就只用算几个点,不用一个一个加了,节省时间。
2.这个数加上这个数管的个数等于下个管他的数。
这两个是一样的,^是其中一个是真一个是假就是真,&是两个都真才是真,第一个我也不会解释
,第二个负数就是取反,加1,比如2是10,取反是01,加1是10,10&10是10,就是2,x&(-x)就是k的值,这个还是很好理解的。。
代码来咯~(有百度参考别人的)
#include<stdio.h>
#include<string.h>
int b[500010],c[500010],N;
typedef struct NNode
{
int index,v;
} Node;
Node node[500010];
int cmp(const void *a,const void *b)
{
return (*((Node *)a)).v-(*((Node *)b)).v;
}
int lowbit(int x) //算k
{
return x&(-x);
}
void add(int i,int v) //构造树状数组
{
while(i<=N)
{
c[i]+=v;
i+=lowbit(i);
}
}
int sum(int i) //算前面已经有多少个数(包括它自己)
{
int s=0;
while(i>0)
{
s+=c[i];
i-=lowbit(i);
}
return s;
}
int main()
{
freopen("D:\\CodeBlocks\\file\\in.txt","r",stdin);
while(scanf("%d",&N),N)
{
int i;
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
for(i=1; i<=N; i++)
{
scanf("%d",&node[i].v);
node[i].index=i;
}
qsort(node+1,N,sizeof(node[1]),cmp); //离散化
b[node[1].index]=1;
for(i=2; i<=N; i++)
if(node[i].v!=node[i-1].v)b[node[i].index]=i;
else b[node[i].index]=b[node[i-1].index];
long long ans=0;
for(i=1; i<=N; i++)
{
add(b[i],1);
ans+=sum(N)-sum(b[i]);
}
printf("%lld\n",ans);
}
return 0;
}
158



被折叠的 条评论
为什么被折叠?



