POJ

来源:互联网 发布:印象主题女装淘宝店 编辑:程序博客网 时间:2024/06/05 20:31

题意:

又是农夫约翰和他的牛,

给定n个牛,每个牛有个听力下限,和位置,他们之间互相说话会有一个 值 = max(听力下限)*  距离


思路:

用两个树状数组,分别维护 (前面比他位置小的数和比他大的数的 个数) 和 (所有位置的和)

详见题解


#include<iostream>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<cmath>#include<set>#include<queue>#include<stack>#include<map>#define PI acos(-1.0)#define in freopen("in.txt", "r", stdin)#define out freopen("out.txt", "w", stdout)#define kuaidian ios::sync_with_stdio(0);using namespace std;typedef long long ll;typedef unsigned long long ull;const int maxn = 2e4 + 7, maxd = 670000 + 7;const ll mod = 1e9 + 7;const int INF = 0x7f7f7f7f;int n, cnt = 0;int id[maxn+1];ll bit[maxn+1] = {0};int bitt[maxn+1] = {0};struct node {    int v, id;}a[maxn];bool cmp(node a, node b) {    return a.v < b.v;}ll sum1(int i) {    ll s = 0;    while(i > 0) {        s += (bit[i]);        i -= (i & -i);    }    return s;}void add1(int i, int x) {    while(i <= maxn) {        bit[i] += x;        i += (i & -i);    }}int sum2(int i) {    ll s = 0;    while(i > 0) {        s += (bitt[i]);        i -= (i & -i);    }    return s;}void add2(int i, int x) {    while(i <= maxn) {        bitt[i] += x;        i += (i & -i);    }}int main() {    kuaidian;    cin >> n;    for(int i = 0; i < n; ++i) {        cin >> a[i].v >> a[i].id;    }    sort(a, a+n, cmp);        add1(a[0].id, a[0].id);    add2(a[0].id, 1);    ll ans = 0;    for(int i = 1; i < n; ++i) {        ll t2 = sum1(a[i].id);        ll t1 = (sum1(maxn) - t2 );        int n1 = sum2(a[i].id);        ans += ( ( t1-(i-n1)*a[i].id + n1*a[i].id-t2 ) * a[i].v );        add2(a[i].id, 1);        add1(a[i].id, a[i].id);    }    cout << ans << endl;    return 0;}