題解:T103180 しろは的軍訓列隊

題目連接node

solution:

按題目隨便假設找到了一個x,它的位置的ap,屬性bpc++

看下圖spa

$$$$$$$$$$$$$$$$|||||P &&&&&&&&&&&&&&&

$:ap前,即ai<ap
&:ap後,即ai>ap
|:ap同,即ai==apcode

顯然要求解下面的式子blog

sigma 1~n (ai-x)*bi

前:(x-a1)*b1+(x-a2)*b2+(x-a3)*b3+......+(x-ap)*bp;

後:(ap+1-x)*bp+1+(ap+2-x)*bp+2+......+(an-x)*bn

展開:

前:b1x-a1b1+b2x-a2b2+b3x-a3b3+......+bpx-apbp

後:ap+1 * bp+1 - bp+1x + ap+2 * bp+2 - bp+2x +.....+ an*bn - bnx

合併:

(b1+b2+..+bp)x-(a1b1+a2b2+a3b3+...+apbp) (1)

(ap+1*bp+1+ap+2*bp+2+...+an*bn)-(bp+1*bp+2+...+bn)x (2)

答案S=(1)+(2)

爲了使S最小

四個∑能夠前綴後綴預處理O(1)查詢

for循環用min肯定要找的x就好了,也就是答案

顯然數據並不是有序,而我又有序的推證,因此要對數據排序

總最高複雜度就是排序nlogn

O(n(long+q) )q常數

#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define int unsigned long long
int n;
struct node{
    int a,b;
    bool operator < (const node & x) const {
        return a<x.a;
    };
}sky[N];
int sum1[N],sum2[N];
 main() {
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%d",&sky[i].a);
    for(int i=1;i<=n;i++) scanf("%d",&sky[i].b);
    sort(sky+1,sky+1+n);
    for(int i=1;i<=n;i++) sum1[i]=sky[i].b+sum1[i-1],sum2[i]=sum2[i-1]+sky[i].a*sky[i].b;
    int ans=LLONG_MAX;
    for(int i=1;i<=n;i++) {
        int x=sky[i].a;
        int temp=0;
        temp=(sum1[i]-sum1[n]+sum1[i])*x;
        temp+=(sum2[n]-sum2[i]-sum2[i]);
        ans=min(ans,temp);
    }
    cout<<ans;
    return 0;
}
相關文章
相關標籤/搜索