瑞士轮,归并排序简化时间
————————————————————————————
// 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; }
————————————————————————————
火柴排队,先利用排序不等式得出需要离散化,再进行离散化后求解逆序对
————————————————————————————————————————