MooFest POJ - 1990

测评传送门

题意:

n 头牛互相对着叫,每头牛有一个 耳背度ai,位置bi;

使得两头牛可以互相听见需要的音量 abs(bi - bj)*max(ai , aj)

求所有牛可以互相听见的总音量

input

4
3 1
2 5
2 6
4 3

output

57

思路:

n方的暴力做法很显然,也很好写,但必挂!

于是就需要用数据结构来优化

 

code

#include<stdio.h> 
#include<algorithm> 
#define lowbit(x) x&(-x)
#define ll long long 
using namespace std;
const int MXN=21000;
struct node {
    int id,pos,val;
}a[MXN];
int n,c[MXN][2];
ll ans;

bool cvp(const node &p,const node &q) {return p.val<q.val;}
bool cop(const node &p,const node &q) {return p.pos<q.pos;}

void add(int x,int k,int d) {
    while(x<=n) {
        c[x][k]+=d;
        x+=lowbit(x);
    }
}

int quer(int x,int k) {
    int re=0;
    while(x) {
        re+=c[x][k];
        x-=lowbit(x);
    } 
    return re;
}

int main() 
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i) {
        scanf("%d%d",&a[i].val,&a[i].pos);    
        add(i,1,1);
    }
    sort(a+1,a+1+n,cop);
    for(int i=1;i<=n;++i) {
        a[i].id=i;
        add(i,0,a[i].pos);
    }
    sort(a+1,a+1+n,cvp);
    for(int i=n;i;--i) {
        add(a[i].id,1,-1);
        add(a[i].id,0,-a[i].pos);
        ans+=(long long)a[i].val*( quer(n,0) - 2*quer(a[i].id,0) + 
             a[i].pos*( quer(a[i].id,1)*2 - quer(n,1)) );
    }
    printf("%lld",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/qseer/p/9819234.html
今日推荐