2 条题解

  • 0
    @ 2025-10-8 17:00:20

    树状数组

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=2e5+10, M = 1e6;
    struct node{int v,x;}a[N];
    int c[2][M+10];
    void add(int x,int k,int *cc){for(;x <= M;x +=x&-x)cc[x] += k;}
    int getsum(int x,int *cc){
        int res = 0;
        for(;x;x -= x&-x)res += cc[x];
        return res;
    }
    
    signed main(){
        int n;scanf("%lld",&n);
        for(int i = 1;i <= n;i ++)scanf("%lld%lld",&a[i].v,&a[i].x);
        sort(a + 1,a + n + 1,[](node x,node y){return x.v < y.v;});
    	memset(c,0,sizeof(c));
    	int ans = 0,presum=0;
        for(int i = 1;i <= n;i ++){
            int num = getsum(a[i].x,c[0]);
            int sum = getsum(a[i].x,c[1]);
            ans += (num * a[i].x - sum) * a[i].v;//小于它
            ans += ((presum - sum) - (i - num - 1) * a[i].x) * a[i].v;//大于它
            add(a[i].x,1,c[0]);//更新
            add(a[i].x,a[i].x,c[1]);
            presum += a[i].x;//前缀和
        }
        printf("%lld\n",ans);
        return 0;
    }
    

    归并排序

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N=2e4+10;
    struct node{LL v, x;} a[N], b[N];
    LL ans;
    bool cmp(node n1, node n2){
        return n1.x>n2.x;
    }
    void mergesort(int l, int r){
        if(l==r) return ;
        int mid=(l+r)/2;
        mergesort(l, mid); mergesort(mid+1, r);
        int lp=l, rp=mid+1, len=0; LL suml=0, sumr=0;
        for(int i=l; i<=mid; i++)   suml+=a[i].x;
        for(int i=mid+1; i<=r; i++) sumr+=a[i].x;
        while(lp<=mid && rp<=r){
            if(a[lp].v>a[rp].v){
                ans+=a[lp].v*abs((r-rp+1)*a[lp].x-sumr);
                suml-=a[lp].x;
                b[++len]=a[lp++];
            }
            else{
                ans+=a[rp].v*abs(suml-(mid-lp+1)*a[rp].x);
                sumr-=a[rp].x;
                b[++len]=a[rp++];
            }
        }
        while(lp<=mid) b[++len]=a[lp++];
        while(rp<=r)   b[++len]=a[rp++];
        for(int i=l; i<=r; i++) a[i]=b[i-l+1];
    }
    int main(){
        int n; scanf("%d", &n);
        for(int i=1; i<=n; i++) scanf("%lld%lld", &a[i].v, &a[i].x);
        sort(a+1, a+n+1, cmp);
        ans=0; mergesort(1, n);
        printf("%lld\n", ans);
        return 0;
    }
    
    • 0
      @ 2025-10-8 17:00:06

      树状数组:

      #include<bits/stdc++.h>
      #define int long long
      using namespace std;
      const int N=2e5+10, M = 1e6;
      struct node{int v,x;}a[N];
      int c[2][M+10];
      void add(int x,int k,int *cc){for(;x <= M;x +=x&-x)cc[x] += k;}
      int getsum(int x,int *cc){
      int res = 0;
      for(;x;x -= x&-x)res += cc[x];
      return res;
      }

      signed main(){ int n;scanf("%lld",&n); for(int i = 1;i <= n;i ++)scanf("%lld%lld",&a[i].v,&a[i].x); sort(a + 1,a + n + 1,[](node x,node y){return x.v < y.v;}); memset(c,0,sizeof(c)); int ans = 0,presum=0; for(int i = 1;i <= n;i ++){ int num = getsum(a[i].x,c[0]); int sum = getsum(a[i].x,c[1]); ans += (num * a[i].x - sum) * a[i].v;//小于它 ans += ((presum - sum) - (i - num - 1) * a[i].x) * a[i].v;//大于它 add(a[i].x,1,c[0]);//更新 add(a[i].x,a[i].x,c[1]); presum += a[i].x;//前缀和 } printf("%lld\n",ans); return 0; }</pre>

      归并排序:

      #include<bits/stdc++.h>
      using namespace std;
      typedef long long LL;
      const int N=2e4+10;
      struct node{LL v, x;} a[N], b[N];
      LL ans;
      bool cmp(node n1, node n2){
      return n1.x>n2.x;
      }
      void mergesort(int l, int r){
      if(l==r) return ;
      int mid=(l+r)/2;
      mergesort(l, mid); mergesort(mid+1, r);
      int lp=l, rp=mid+1, len=0; LL suml=0, sumr=0;
      for(int i=l; i<=mid; i++)   suml+=a[i].x;
      for(int i=mid+1; i<=r; i++) sumr+=a[i].x;
      while(lp<=mid && rp<=r){
      if(a[lp].v>a[rp].v){
      ans+=a[lp].v*abs((r-rp+1)a[lp].x-sumr);
      suml-=a[lp].x;
      b[++len]=a[lp++];
      }
      else{
      ans+=a[rp].vabs(suml-(mid-lp+1)*a[rp].x);
      sumr-=a[rp].x;
      b[++len]=a[rp++];
      }
      }
      while(lp<=mid) b[++len]=a[lp++];
      while(rp<=r)   b[++len]=a[rp++];
      for(int i=l; i<=r; i++) a[i]=b[i-l+1];
      }
      int main(){
      int n; scanf("%d", &n);
      for(int i=1; i<=n; i++) scanf("%lld%lld", &a[i].v, &a[i].x);
      sort(a+1, a+n+1, cmp);
      ans=0; mergesort(1, n);
      printf("%lld\n", ans);
      return 0;
      }

      • 1

      *【树状数组|归并排序】[USACO04OPEN] MooFest G(数据加强)

      信息

      ID
      2190
      时间
      200ms
      内存
      128MiB
      难度
      9
      标签
      递交数
      42
      已通过
      5
      上传者