poj 1990 树状数组

来源:互联网 发布:nginx怎么用 编辑:程序博客网 时间:2024/05/11 15:29

开始对距离排序 然后果断的TLE了

然后发现应该对power排序,然后我们记录和更新的是 比x小的个数与距离和,然后每次算的时候,因为按power排序了,当前的pi一定是最大的,所以就能在logdistance的时间内算出来

AC代码如下:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int MAX_X = 20000 + 5;struct Node{    long long v, d;};long long sum[MAX_X], num[MAX_X];int N;Node node[MAX_X];bool cmp( Node a, Node b ){    if( a.v < b.v ){        return true;    }else{        return false;    }}inline int lowbit( int x ){    return x&-x;}long long getsum( int x ){    int ans = 0;    while( x > 0 ){        ans += sum[x];        x -= lowbit( x );    }    return ans;}long long getnum( int x ){    int ans = 0;    while( x > 0 ){        ans += num[x];        x -= lowbit( x );    }    return ans;}void updata( int x, long long d ){    while( x <= MAX_X ){        sum[x] += d;        num[x] += 1;        x += lowbit( x );    }}int main(){    while( scanf( "%d", &N ) != EOF ){        for( int i = 1; i <= N; i++ ){            scanf( "%lld%lld", &node[i].v, &node[i].d );        }        sort( node + 1, node + 1 + N, cmp );        memset( sum, 0, sizeof( sum ) );        memset( num, 0, sizeof( num ) );        int t[MAX_X];        t[0] = 0;        for( int i = 1; i <= N; i++ ){            t[i] = t[i-1] + node[i].d;        }        long long ans = 0;        for( int i = 1; i <= N; i++ ){            int t1 = getsum( node[i].d );            int t2 = getnum( node[i].d );            int t3 = t[i-1] - t1;            int t4 = i - 1 - t2;            ans += node[i].v * ( t2 * node[i].d - t1 + t3 - t4 * node[i].d );            updata( node[i].d, node[i].d );        }        printf( "%lld\n", ans );    }    return 0;}


0 0
原创粉丝点击