您的位置:首页 > 其它

poj 1007

2014-04-08 14:08 288 查看
题目链接

m个字符串以逆序对个数排序后输出

以前都是用线段树写的 现在加上归并

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

struct xx
{
string str;
int inv;
}a[100];

int ans;

string str;

bool cmp(const xx &a,const xx &b)
{
return a.inv<b.inv;
}

void merge(int l,int r)
{
if(l+1>=r)
{
return;
}
int m=(l+r)>>1;
merge(l,m);
merge(m,r);
for(int i=l;i<m;i++)
{
ans+=lower_bound(str.begin()+m,str.begin()+r,str[i])-(str.begin()+m);
}
inplace_merge(str.begin()+l,str.begin()+m,str.begin()+r);
}

int cal()
{
ans=0;
merge(0,str.size());
return ans;
}

int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<m;i++)
{
cin>>a[i].str;
str=a[i].str;
a[i].inv=cal();
}
sort(a,a+m,cmp);
for(int i=0;i<m;i++)
cout<<a[i].str<<endl;
system("pause");
return 0;
}
以前的代码

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>

using namespace std;

#define maxn 4
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

struct xx
{
string str;
int inv;
}a[100];

int sum[maxn<<2];

bool cmp(const xx &a,const xx &b)
{
return a.inv<b.inv;
}

int cal(char c)
{
switch(c)
{
case 'A': return 1;
case 'C': return 2;
case 'G': return 3;
case 'T': return 4;
}
}

int query(int L,int R,int l,int r,int rt)
{
if(L>R)
return 0;
if(L<=l&&r<=R)
{
return sum[rt];
}
int m=(l+r)>>1;
int ret=0;
if(L<=m)
ret+=query(L,R,lson);
if(R>m)
ret+=query(L,R,rson);
return ret;
}

void updata(int c,int l,int r,int rt)
{
if(l==r)
{
if(l==c)
sum[rt]++;
return;
}
int m=(l+r)>>1;
if(c<=m)
updata(c,lson);
else
updata(c,rson);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}

int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<m;i++)
{
cin>>a[i].str;
memset(sum,0,sizeof(sum));
a[i].inv=0;
for(int j=0;j<a[i].str.size();j++)
{
a[i].inv+=query(cal(a[i].str[j])+1,4,1,4,1);
updata(cal(a[i].str[j]),1,4,1);
}
}
sort(a,a+m,cmp);
for(int i=0;i<m;i++)
cout<<a[i].str<<endl;
// system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  分治 线段树