逆序对
1.Luogu P1908 逆序对
-
归并排序
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int N=5e5+5;
int n,a[N],b[N];
LL ans;
void merge(int l,int r)
{
if(l==r) return;
int mid=(l+r)>>1;
merge(l,mid);
merge(mid+1,r);
int x=l,y=mid+1,z=l;
while(x<=mid&&y<=r)
{
if(a[x]>a[y])
{
b[z++]=a[y++];
ans+=mid-x+1;
}
else b[z++]=a[x++];
}
while(x<=mid) b[z++]=a[x++];
while(y<=r) b[z++]=a[y++];
for(int i=l;i<=r;i++) a[i]=b[i];
return;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
merge(1,n);
printf("%lld\n",ans);
return 0;
}
-
树状数组
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int N=5e5+5;
struct number
{
int pos,val;
}a[N];
int n,r[N],c[N];
LL ans;
bool cmp(number a,number b)
{
if(a.val==b.val) return a.pos<b.pos;
else return a.val<b.val;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x)
{
for(;x<=n;x+=lowbit(x)) c[x]++;
return;
}
int sum(int x)
{
int res=0;
for(;x;x-=lowbit(x)) res+=c[x];
return res;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
a[i].pos=i;
scanf("%d",&a[i].val);
}
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++) r[a[i].pos]=i;
for(int i=1;i<=n;i++)
{
add(r[i]);
ans+=i-sum(r[i]);
}
printf("%lld\n",ans);
return 0;
}
2.Luogu P5149 会议座位
这道题就是求逆序对,加了一步字符串的转化
-
归并排序
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
#define LL long long
using namespace std;
const int N=1e5+5;
int n,b[N],c[N];
char ch[5];
LL ans;
map< string,int > a;
void merge(int l,int r)
{
if(l==r) return;
int mid=(l+r)>>1;
merge(l,mid);
merge(mid+1,r);
int x=l,y=mid+1,z=l;
while(x<=mid&&y<=r)
{
if(b[x]>b[y])
{
c[z++]=b[y++];
ans+=mid-x+1;
}
else c[z++]=b[x++];
}
while(x<=mid) c[z++]=b[x++];
while(y<=r) c[z++]=b[y++];
for(int i=l;i<=r;i++) b[i]=c[i];
return;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>ch;
a[ch]=i;
}
for(int i=1;i<=n;i++)
{
cin>>ch;
b[i]=a[ch];
}
merge(1,n);
printf("%lld\n",ans);
return 0;
}
-
树状数组
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
#define LL long long
using namespace std;
const int N=1e5+5;
struct meet
{
int pos,val;
}b[N];
int n,c[N],d[N];
char ch[5];
LL ans;
map< string,int > a;
bool cmp(meet a,meet b)
{
if(a.val==b.val) return a.pos<b.pos;
else return a.val<b.val;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x)
{
for(;x<=n;x+=lowbit(x)) c[x]++;
return;
}
int sum(int x)
{
int res=0;
for(;x;x-=lowbit(x)) res+=c[x];
return res;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>ch;
a[ch]=i;
}
for(int i=1;i<=n;i++)
{
cin>>ch;
b[i].pos=i;
b[i].val=a[ch];
}
sort(b+1,b+n+1,cmp);
for(int i=1;i<=n;i++) d[b[i].pos]=i;
for(int i=1;i<=n;i++)
{
add(d[i]);
ans+=i-sum(d[i]);
}
printf("%lld\n",ans);
return 0;
}
Classical is something not fade,but grow more precious with time pass by,so is dream.梦想这东西和经典一样,永远不会因为时间而褪色,反而更显珍贵。