您的位置:首页 > 产品设计 > UI/UE

POJ 2299 Ultra-QuickSort

2016-08-20 23:10 375 查看
如有错误,欢迎大神指出!!!

新手最近刚刚学树状数组,天啊撸感觉很崩溃!!

直接开题!

题解:我的想法就是往前找更大的数。比如说9,1,0,5,4,第一个数毫无疑问前面没有其他数字所以是sum=0,第二个数1,前面有9,所以sum=1,以此类推,sum=0+1+2+1+2=6。

不过数据太大需要预处理,度娘了一下说什么离散化(没怎么懂……)我就用结构体来记录下标更改原先的值。(说的不清楚,看代码吧)

ac code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
using namespace std;

#define si1(a) scanf("%d",&a)
#define si2(a,b) scanf("%d%d",&a,&b)
#define sd1(a) scanf("%lf",&a)
#define sd2(a,b) scanf("%lf%lf",&a,&b)
#define ss1(s) scanf("%s",s)
#define pi1(a) printf("%d\n",a)
#define pi2(a,b) printf("%d %d\n",a,b)
#define mset(a,b) memset(a,b,sizeof(a))
#define forb(i,a,b) for(int i=a;i<b;i++)
#define ford(i,a,b) for(int i=a;i<=b;i++)

typedef long long LL;
const int N=1100001;
const int M=6666666;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-7;
#define maxn 520000

struct p
{
int val,cpy;//val是原先的值,cpy是改了的值(之后有)
int indel;//记录下标
}a[maxn];

int b[maxn],c[maxn],n;
bool cmp(p a,p b)
{
if(a.val!=b.val)
return a.val<b.val;//从小到大排
else
return a.indel<b.indel;
}

int lowbit(int x)
{
return x&(-x);
}

int sum(int x)
{
int ret=0;
while(x<=n)//往前找更大数
{
ret+=c[x];
x+=lowbit(x);//注意是加等,因为找更大的
}
return ret;
}

void update(int x)
{
while(x>0)//往上更新数据
{
c[x]++;
x-=lowbit(x);
}
}

int main()
{
while(~scanf("%d",&n),n)
{
mset(c,0);
mset(a,0);
ford(i,1,n)
{
si1(a[i].val);//输入数据
a[i].indel=i;
}
sort(a+1,a+n+1,cmp);
a[1].cpy=1;//记录相对大小
ford(i,2,n)
{
if(a[i].val==a[i-1].val)
a[i].cpy=a[i-1].cpy;//注意如果数据重复,则跟之前一样
else
a[i].cpy=a[i-1].cpy+1;
}
ford(i,1,n)
{
b[a[i].indel]=a[i].cpy;//新的数组来表示原来数组,数据相对变小
}
LL ans=0;
ford(i,1,n)
{
ans+=sum(b[i]);
update(b[i]);
}
printf("%lld\n",ans);
}
return 0;
}


可能比较复杂,如有简单方法,欢迎评论!一定虚心接受!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: