• 逆序对


    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
    ",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
    ",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
    ",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
    ",ans);
    	return 0;
    }
    
    Classical is something not fade,but grow more precious with time pass by,so is dream.梦想这东西和经典一样,永远不会因为时间而褪色,反而更显珍贵。
  • 相关阅读:
    组合数学
    组合数学
    组合数学
    组合数学 + STL --- 利用STL生成全排列
    组合数学
    数论
    给xcode项目重命名
    iOS中动态注入JavaScript方法。动态给html标签添加事件
    swift
    swift
  • 原文地址:https://www.cnblogs.com/Hawking-llfz/p/11468820.html
Copyright © 2020-2023  润新知