• 【题解】[NOIP2013 提高组] 火柴排队


    ZZ菜鸡犯傻了……被旁边 gzh 神仙秒了并 D 了一番……过来写个题解。

    Problem

    ( ext{Solution:})

    离散化一下,把式子推一下:

    [sum (a_i-b_i)^2=sum a_i^2+b_i^2 +sum a_icdot b_i ]

    前面两个是定值,要处理最后一坨式子。

    首先可以贪心地证明,顺序乘积大于乱序乘积,因为要使大的值乘的数尽量大。

    于是一种 逆序对 的既视感很清晰了。但是傻逼的我竟然傻逼到不知道怎么将一个排列交换成一个排列的最小交换次数怎么求。

    显然地,对一个序列的位置与值进行映射,进而映射到另一个序列中,得到的新序列交换到 ([1,2,3...]) 的最小交换次数就是答案。

    这一步其实相当于将一列火柴的位置映射到了另一列火柴上。从而将原问题转化成了一个求逆序对的经典问题。

    总结:菜是原罪,我是傻逼。 膜拜 gzh 神仙 Orz

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int MAXN=3e5+10;
    const int mod=1e8-3;
    int a[MAXN],b[MAXN];
    int A[MAXN],B[MAXN],pos[MAXN];
    int Acnt,Bcnt,Alen,Blen,Ccnt,Clen;
    int ls[MAXN],rs[MAXN],L[MAXN],R[MAXN],sum[MAXN],rt,node;
    inline void pushup(int x){sum[x]=sum[ls[x]]+sum[rs[x]];}
    struct Qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq{int x,y;}q[MAXN];
    inline int getposA(int x){return lower_bound(A+1,A+Alen+1,x)-A;}
    inline int getposB(int x){return lower_bound(B+1,B+Blen+1,x)-B;}
    void build(int &x,int l,int r){
    	x=++node;
    	L[x]=l;R[x]=r;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	build(ls[x],l,mid);
    	build(rs[x],mid+1,r);
    	pushup(x);
    }
    void change(int x,int pos,int v){
    	if(L[x]==R[x]){
    		sum[x]=v;
    		return;
    	}
    	int mid=(L[x]+R[x])>>1;
    	if(pos<=mid)change(ls[x],pos,v);
    	else change(rs[x],pos,v);
    	pushup(x);
    }
    int query(int x,int l,int r){
    	if(L[x]>=l&&R[x]<=r)return sum[x];
    	int mid=(L[x]+R[x])>>1;
    	int res=0;
    	if(l<=mid)res+=query(ls[x],l,r);
    	if(mid<r)res+=query(rs[x],l,r);
    	return res;
    }
    inline long long Abs(long long x){
    	if(x<0)x=-x;
    	return x;
    }
    int n,qcnt;
    signed main(){
    	scanf("%lld",&n);
    	long long ans=0;
    	for(int i=1;i<=n;++i)scanf("%lld",&a[i]);
    	for(int i=1;i<=n;++i)scanf("%lld",&b[i]);
    	for(int i=1;i<=n;++i)A[++Acnt]=a[i],B[++Bcnt]=b[i];
    	sort(A+1,A+Acnt+1);sort(B+1,B+Bcnt+1);
    	Alen=unique(A+1,A+Acnt+1)-A-1;
    	Blen=unique(B+1,B+Bcnt+1)-B-1;
    	for(int i=1;i<=n;++i){
    		a[i]=getposA(a[i]);
    		b[i]=getposB(b[i]);
    	}
    	build(rt,1,n);
    	for(int i=1;i<=n;++i)pos[a[i]]=i;
    	for(int i=1;i<=n;++i)b[i]=pos[b[i]];
    	for(int i=1;i<=n;++i){
    		ans+=query(rt,b[i]+1,n);
    		change(rt,b[i],1);
    		ans%=mod;
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    .Net Core 为 x86 和 x64 程序集编写 AnyCPU 包装
    动态构造任意复杂的 Linq Where 表达式
    Windows GDI 窗口与 Direct3D 屏幕截图
    你一定看得懂的 DDD+CQRS+EDA+ES 核心思想与极简可运行代码示例
    浏览器中的 .Net Core —— Blazor WebAssembly 初体验
    Asp.Net Core IdentityServer4 管理面板集成
    Asp.Net Core Identity 骚断腿的究极魔改实体类
    lambda函数的作用
    风控模型师面试准备--业务+模型篇
    梯度下降算法原理讲解
  • 原文地址:https://www.cnblogs.com/h-lka/p/14943064.html
Copyright © 2020-2023  润新知