zoukankan      html  css  js  c++  java
  • 题解P2345 奶牛集会

    题目

    一道树状数组的题。

    话说题目直接告诉做法是什么鬼?

    首先这个题直接暴力是(O(n^2))的,不能通过(评论里说可以?可能数据太水了,建议加强

    考虑优化,首先对于答案里的(max),可以直接通过排序优化掉,即把数据从小到大排序,每次更新答案的时候就直接使用当前的(V)就可以了。

    之后看这个式子:(|X_i - X j|)。单独看没有什么特点,但是如果我们对于(i),讨论一下(j),就可以发现规律。显然对于(j),可以分成两类,即({j_1|X_{j1}<X_i })({ j_2|X_{j2}>X_i })。设当前(i)两边分别有(x_1,x_2)(j),那么答案就是((x_1 imes X_i- Sigma X_{j1})+(Sigma X_{j2}-x_2 imes X_i))

    显然对于(Sigma X_{j1}),可以用前缀和直接求出。对于(Sigma X_{j2}),只需要用总的减去(Sigma X_{j1})就可以求出。

    (x_1,x_2)同理也可以求出

    这里选择树状数组。

    最后别忘了开longlong,否则100pts->45pts。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 20005;
    typedef long long ll;
    int n;
    ll iAns, iSum[N], iCnt[N];
    struct sCow
    {
    	int V, X;
    }cow[N];
    
    inline bool cmp(sCow a, sCow b){return a.V < b.V;}
    inline int lowbit(int x){return x & -x;}
    inline void Add(int x, int k){for(; x <= N; x += lowbit(x)) iSum[x] += k, iCnt[x] += 1;}
    inline void Query(int x, ll &ans, int &cnt){ans = 0, cnt = 0;for(; x; x -= lowbit(x)) ans += iSum[x], cnt += iCnt[x];}
    int main()
    {
    	scanf("%d", &n);
    	for(int i = 1; i <= n; i++) scanf("%d%d", &cow[i].V, &cow[i].X);
    	sort(cow + 1, cow + 1 + n, cmp);
    	ll S = 0, C = 0;
    	for(int i = 1; i <= n; i++)
    	{
    		ll ans = 0;
    		int cnt = 0;
    		Query(cow[i].X, ans, cnt);
    		iAns += cow[i].V * (cnt * cow[i].X - ans);
    		iAns += cow[i].V * ((S - ans) - (C - cnt) * cow[i].X);
    		Add(cow[i].X, cow[i].X);
    		S += cow[i].X, C +=1;
    	}
    	cout << iAns;
    }
    
  • 相关阅读:
    Excel中的日期时间计算,套路很全
    WPS表格 制作甘特图
    关于海康威视与Unity3d集成冲突问题解决
    海康威视(iOS集成)
    Objective-C
    Android中windowTranslucentStatus与windowTranslucentNavigation的一些设置(转)
    Could not symlink include/node/android-ifaddrs.h
    dyld`__abort_with_payload:
    about the libiconv.2.dylib
    Intent的作用和表现形式简单介绍
  • 原文地址:https://www.cnblogs.com/lcezych/p/12773457.html
Copyright © 2011-2022 走看看