逆序对问题P1309,P1908,P1966

瑞士轮,归并排序简化时间

————————————————————————————

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
struct node{int w,st,id;}num[100001*2],a[100001*2],b[100001*2];
int n,r,q;
int cmp(node x,node y){if(x.w==y.w)return x.id<y.id;else  return x.w>y.w;}
void gb()
{
    int p1=1,p2=1;
    for(int i=1;i<=n*2;i++)
    if(a[p1].w>b[p2].w||(a[p1].w==b[p2].w&&a[p1].id<b[p2].id))
    num[i]=a[p1++];
    else num[i]=b[p2++];
}
int main()
{
    cin>>n>>r>>q;
    for(int i=1;i<=n*2;i++)cin>>num[i].w;
    for(int i=1;i<=n*2;i++)cin>>num[i].st;
    for(int i=1;i<=n*2;i++)num[i].id=i;
    sort(num+1,num+1+2*n,cmp);
    while(r--)
    {
    
        for(int i=1;i<=2*n;i=i+2)
        if(num[i].st>num[i+1].st)
        {a[i/2+1]=num[i];b[i/2+1]=num[i+1];a[i/2+1].w++;}
        else 
        {a[i/2+1]=num[i+1];b[i/2+1]=num[i];a[i/2+1].w++;}    
        gb();
    }
    cout<<num[q].id;
}

逆序对,使用归并排序统计

————————————————————————

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
int n,a[500010],b[500010];
ll ans;
int read()
{
    int fg=1;ll cn=0;char ch=getchar();
    while((ch<'0'||ch>'9')){if(ch=='-')fg=-1;ch=getchar();}
    while((ch>='0'&&ch<='9'))cn=cn*10+ch-'0',ch=getchar();
    return cn*fg;
}
void msort(int l,int r)
{
    if(l==r)return;
    int mid=(l+r)/2;
    msort(l,mid);msort(mid+1,r);
    int p1=l,p2=mid+1,k=l;
    while(p1<=mid&&p2<=r)
        if(a[p1]<=a[p2])b[k++]=a[p1++];
        else b[k++]=a[p2++],ans+=(ll)(mid-p1+1);
    while(p1<=mid)b[k++]=a[p1++];
    while(p2<=r)b[k++]=a[p2++];
    for(int i=l;i<=r;i++)a[i]=b[i];
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
    a[i]=read();
    msort(1,n);
    cout<<ans;
}

————————————————————————————

火柴排队,先利用排序不等式得出需要离散化,再进行离散化后求解逆序对

————————————————————————————————————————

猜你喜欢

转载自www.cnblogs.com/SFWR-YOU/p/11025608.html