zoukankan      html  css  js  c++  java
  • 题解:T103180 しろは的军训列队

    题目链接

    solution:

    按题目随便假设找到了一个x,它的位置的ap,属性bp

    看下图

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

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

    显然要求解下面的式子

    
    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;
    }
    
  • 相关阅读:
    类加载
    LinkedList插入排序实现
    99乘法表
    关于IO流的抽象类
    分解质因数
    Struts2小demo遇到的几个问题
    Tomcat设置欢迎页问题
    数据库迁移
    EF – 1.模式
    正则表达式
  • 原文地址:https://www.cnblogs.com/skkyk/p/11667059.html
Copyright © 2011-2022 走看看