description
你和你的伙伴正在筹备村里的万人宴,由于村子是长条形的,所有宾客将坐在一张超级长桌的一侧就餐。
正当筹备工作进行得火热朝天,你和你的伙伴发现一个严重问题:由于缺乏沟通,你俩各自制作了一张座位图发给各位宾客。你必须计算出有多少对宾客,他们在两份座位图中次序安排是不同的。
例如,对以下两份座位图:
A B C D E
B A D E C
有三对宾客(A,B),(C,D)和(C,E),他们在两份座位图中的次序不同。
analysis
-
逆序对,归排或树状数组搞定
-
注意哈希细节
code
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 100005
#define mod 1000033
#define ll long long
#define fo(i,a,b) for (ll i=a;i<=b;++i)
#define fd(i,a,b) for (ll i=a;i>=b;--i)
using namespace std;
ll a[MAXN],b[MAXN];
char st[6];
ll n,ans;
struct node
{
char st[6];
ll x,id;
bool bz;
}hash[mod+5];
inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline ll turn(char st[])
{
ll tot=0,len=strlen(st);
fo(i,0,len)(tot*=100)+=st[i];
return tot;
}
inline bool judge(char st1[],char st2[])
{
ll len1=strlen(st1),len2=strlen(st2);
if (len1!=len2)return 0;
fo(i,0,len1-1)if (st1[i]!=st2[i])return 0;
return 1;
}
inline void hash_in(ll x,ll y,char st[])
{
ll now=x%mod;
while (hash[now].bz)(now+=1)%=mod;
hash[now].x=x,hash[now].id=y,strcpy(hash[now].st,st),hash[now].bz=1;
}
inline ll hash_query(ll x,char st[])
{
ll now=x%mod;
while ((hash[now].bz && hash[now].x!=x) ||
(hash[now].bz && hash[now].x==x && !judge(hash[now].st,st)))(now+=1)%=mod;
if (judge(hash[now].st,st))return hash[now].id;
}
inline void msort(ll l,ll r)
{
if (l==r)return;
ll mid=(l+r)>>1,i=l,j=mid+1,k=l;
msort(l,mid),msort(mid+1,r);
while (i<=mid && j<=r)
{
if (a[i]<=a[j])b[k++]=a[i++];
else b[k++]=a[j++],ans+=mid-i+1;
}
while (i<=mid)b[k++]=a[i++];
while (j<=r)b[k++]=a[j++];
fo(i,l,r)a[i]=b[i];
}
int main()
{
n=read();
fo(i,1,n)
{
scanf("%s",&st);
hash_in(turn(st),i,st);
}
fo(i,1,n)
{
scanf("%s",&st);
a[i]=hash_query(turn(st),st);
}
msort(1,n),printf("%lld\n",ans);
return 0;
}

解决一个村庄万人宴的座次安排冲突问题,通过计算不同宾客在两张座位图上的次序变化,利用逆序对、归并排序和树状数组等算法高效找出所有次序不一致的宾客对。
2186

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



