• acdream1174 合并同类项


    这题说的是

    给出N,a[1]... a[N],还有M,b[1]... b[M]
    long long ans = 0;
    for(int i = 1; i <= N; i ++)
        for(int j = 1; j <= M; j ++)
            ans += abs(a[i] - b[j]) * (i - j); NM【1,50000】 快熟计算出ans 3 秒 当画出这个乘法表后救就会发现 将b[i] 合并,然后合并完同类项就可以做了 效率 mlogn 使用stl的二分还不行卡常数太不合理了

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <algorithm>
    #include <vector>
    using namespace std;
    typedef long long ll;
    const int max_n =100005;
    struct point{
        int v,num;
        point(ll a=0, ll b=0){
          v=a; num=b;
        }
        bool operator <(const point A)const {
          return v<A.v||(v==A.v&&num<A.num);
        }
    }P[max_n];
    int n,m;
    int B[max_n],A[max_n],K[max_n];
    ll perAsum[max_n],perAnum[max_n],perAper[max_n];
    int binser(int n, int v){
          int L=0, R =n;
          while(L<R){
            int mid = (L+R)/2;
            if(K[mid]<=v) L=mid+1;
            else R=mid;
          }
          return L;
    }
    int main()
    {
         ll two=2,one =1;
         int cas=0;
          /*freopen("data.in","r",stdin);
            freopen("data.out","w",stdout);
        */while(scanf("%d%d",&n,&m)==2){
              int V;
              ll num=one*(n-1)*n/two;
             for(int i=0; i<n; ++i){
                  scanf("%d",&V);
                  A[i]=V;
                  P[i]=point(V,i);
             }
             for(int i=0; i<m; ++i)
                scanf("%d",&B[i]);
             ll colu=0,per=0;
             for(int i =0; i<n; i++){
                 colu=colu+one*A[i]*i;
                 per=per+A[i];
             }
             ll ans=0;
             for(int i=0; i<m; ++i){
                 ans = ans+ colu;
                 colu= colu - per;
                 ans = ans - one*B[i]*num;
                 num = num - n;
             }
             sort(P,P+n);
             perAnum[0]=P[0].num;
             perAsum[0]=one*P[0].v*P[0].num;
             perAper[0]=P[0].v;
             K[0]=P[0].v;
             for(int i=1; i<n; ++i){
                 perAnum[i] = perAnum[i-1]+P[i].num;
                 perAsum[i] = perAsum[i-1]+one*P[i].num*P[i].v;
                 perAper[i] = perAper[i-1]+P[i].v;
                 K[i]=P[i].v;
             }
             for(int i=0; i<m; ++i){
                 int loc = binser(n,B[i]);
                 if(loc<=0)continue;
                 loc-=1;
                 ll perA = perAsum[loc]-perAper[loc]*i;
                 ll perB = B[i]*(perAnum[loc]-one*(loc+1)*i);
                 ans = ans - ( perA-perB )*two;
             }
              printf("%I64d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    POJ Problem 2631 Roads in the North【树的直径】
    POJ Problem 1985 Cow Marathon 【树的直径】
    Light OJ 1049 Farthest Nodes in a Tree【树的直径】
    HDU Problem 4707 Pet【并查集】
    HDU Problem 1325 Is It A Tree?【并查集】
    HDU Problem 5631 Rikka with Graph【并查集】
    HDU Problem 5326 Work 【并查集】
    文件比较软件修改比较文件时间戳方法
    什么是Oracle 数据泵
    文件对比工具文件上传 FTP如何匹配本地文件
  • 原文地址:https://www.cnblogs.com/Opaser/p/3988731.html
Copyright © 2020-2023  润新知