洛谷1966 火柴排队
洛谷1966 火柴排队
原题链接
交题记录
23:33 10'
23:38 10'
23:40 0'
15:32 AC
题解
首先肯定要先离散化然后根据排名一一对应
怎么交换?
肯定可以一个不动另一个动去交换
那么怎么办?重新赋一个标号。
将a变成1 2 3 4 5 ... n
,答案就是b的逆序对数。
那么假设\(f[a]==b\)表示a中标号a变成b,实现方法就是
for i=1...n do f[a[i]]=i
a重新赋标号之后再给b重新赋标号。
for i=1...n do b[i]=f[b[i]]
整合一下
for i=1...n do f[a[i]]=i
for i=1...n do b[i]=f[b[i]]
需要注意的是求b的逆序对数就用不到a了
Code
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define lb(o) (o&-o)
#define vd void
typedef long long ll;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int maxn=100010;
int a[maxn],b[maxn];
int p[maxn],q[maxn];
int n;
int f[maxn];
int tree[maxn];
il vd add(int pos){while(pos<=n)++tree[pos],pos+=lb(pos);}
il int sum(int pos){int ret=0;while(pos)ret+=tree[pos],pos-=lb(pos);return ret;}
int main(){
n=gi();
rep(i,1,n)a[i]=p[i]=gi();
rep(i,1,n)b[i]=q[i]=gi();
sort(p+1,p+1+n);
sort(q+1,q+1+n);
rep(i,1,n)a[i]=lower_bound(p+1,p+1+n,a[i])-p;
rep(i,1,n)b[i]=lower_bound(q+1,q+1+n,b[i])-q;
rep(i,1,n)f[a[i]]=i;
rep(i,1,n)b[i]=f[b[i]];
int ans=0;
rep(i,1,n)add(b[i]),ans=(ans+i-sum(b[i]))%99999997;
printf("%d\n",ans);
return 0;
}
这里还有一种解法我不太懂。。。
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define lb(o) (o&-o)
#define vd void
typedef long long ll;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int maxn=100010;
struct num{
int s,id;
bool operator < (num o){return s<o.s;}
}a[maxn],b[maxn];
int n;
int t[maxn];
int tree[maxn];
il vd add(int pos){while(pos<=n)++tree[pos],pos+=lb(pos);}
il int sum(int pos){int ret=0;while(pos)ret+=tree[pos],pos-=lb(pos);return ret;}
int main(){
n=gi();
rep(i,1,n)a[i]=(num){gi(),i};
rep(i,1,n)b[i]=(num){gi(),i};
sort(a+1,a+1+n);
sort(b+1,b+1+n);
rep(i,1,n)t[a[i].id]=b[i].id;
int ans=0;
rep(i,1,n)add(t[i]),ans=(ans+i-sum(t[i]))%99999997;
printf("%d\n",ans);
return 0;
}
博主是蒟蒻,有问题请指出,谢谢!
本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。
本博客中博文均为原创,未经博主允许请勿随意转载,谢谢。