POJ2299题解node
2019-12-28ios
Powered by Gauss算法
1.题目传送门:POJ2299数组
2.理解题意:数据结构
作题的时候,第一步也是最重要的就是理解题意。记住这句话。函数
POJ2299是一道标准的树状数组模板题。题意大体以下:spa
快速排序是一种很是优秀的排序方式,其精华在于循环比较和swap函数的应用。.net
先给你一个数N,表示这组数据(没错,这题是多组数据)数的个数,以后的N行,每行一个数Aicode
请你输出在快速排序过程当中经历的swap函数的次数。blog
3.算法思路:
树状数组是一种很是高效的数据结构,因为篇幅有限,这里不作讲解,做者将尽快写出一篇树状数组的稿子,敬请谅解。
树状数组的精华在于lowbit函数的使用,为了迎合题目,这里将query函数和update函数作了一些改动。
void update(int x,int k) { int i; for(i=x;i<=n;i=i+lowbit(i)) { tree[i]+=k; } }
int query(int x) { int i,sum=0; for(i=x;i>0;i=i-lowbit(i)) { sum+=tree[i]; } return sum; }
咱们由于这道题的数据规模很是大,因此要用到一些离散化的思想。
for(i=1;i<=n;i++) { cin>>a[i].value; a[i].id=i; } sort(a+1,a+n+1,cmp); for(i=1;i<=n;i++) { a[i].pos=i; }
有了离散化,咱们就能够大大下降时间复杂度了。
上面那段代码中,咱们用结构体node来实现,包含三个参数,id,pos和value。
struct node { int id,value,pos; }a[500001];
最后,结合树状数组的计算模板,咱们给出最后的AC源代码,用时3610MS:
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> using namespace std; int tree[500001],n; struct node { int id,value,pos; }a[500001]; int lowbit(int x) { return (x&(-x)); } void update(int x,int k) { int i; for(i=x;i<=n;i=i+lowbit(i)) { tree[i]+=k; } } int query(int x) { int i,sum=0; for(i=x;i>0;i=i-lowbit(i)) { sum+=tree[i]; } return sum; } int cmp(node a,node b) { return a.value<b.value; } int cmp1(node a,node b) { return a.id<b.id; } int main() { int i; long long sum; while(cin>>n && n) { sum=0; memset(tree,0,sizeof(tree)); for(i=1;i<=n;i++) { cin>>a[i].value; a[i].id=i; } sort(a+1,a+n+1,cmp); for(i=1;i<=n;i++) { a[i].pos=i; } sort(a+1,a+n+1,cmp1); for(i=1;i<=n;i++) { sum+=i-1-query(a[i].pos); update(a[i].pos,1); } cout<<sum<<endl; } return 0; }
版权声明:知识产权神圣不可侵犯,这篇文章中的部分代码和思想源自:https://blog.csdn.net/weixin_43918531/article/details/87950037