poj1990(树状数组好题)

来源:互联网 发布:纪录片推荐 知乎 编辑:程序博客网 时间:2024/06/08 16:26

思路请参考:http://blog.csdn.net/allenlsy/article/details/5884428

下面是我的代码:

#include<iostream>#include<algorithm>#include<cstring>#include<string>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdlib.h>#include<math.h>#define LL __int64#define N 20005#define inf 0x7ffffff#define eps 1e-9#define pi acos(-1.0)using namespace std;struct node{    int vol,x;}s[N];int c[N],countt[N];//c是树状数组,countt[i]记录比音量比i小下标比牛i小的牛的个数int total[N];//total[i]表示音量比牛i小的牛且下标比牛i小的牛的下标和int alltotal[N];//alltotal[i]表示音量比牛i小的牛的下标和bool cmp(node a,node b){    if(a.vol != b.vol)        return a.vol < b.vol;    return a.x < b.x;}int lowbit(int x){    return x&(-x);}void update(int x, int v){    for(int i = x; i <= 20000; i += lowbit(i))        c[i] += v;}int sum(int x){    int ans = 0;    for(int i = x; i > 0; i -= lowbit(i))        ans += c[i];    return ans;}int main(){//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);    int n;    while(scanf("%d",&n) != EOF)    {        int i;        for(i = 0; i < n; i++)            scanf("%d%d",&s[i].vol,&s[i].x);        sort(s,s+n,cmp);        memset(c,0,sizeof(c));        memset(countt,0,sizeof(countt));        for(i = 0; i < n; i++)        {            countt[i] = sum(s[i].x);            update(s[i].x,1);        }        memset(c,0,sizeof(c));        memset(total,0,sizeof(total));        for(i = 0; i < n; i++)        {            total[i] = sum(s[i].x);            update(s[i].x,s[i].x);        }        LL ans = 0;        memset(alltotal,0,sizeof(alltotal));        for(i = 1; i < n; i++)            alltotal[i] = alltotal[i-1] + s[i-1].x;        for(i = 1; i < n; i++)        {            //cout<<countt[i]*s[i].x - total[i]<<" "<< alltotal[i]<<" "<<total[i]<<" ";            ans = ans + (1LL)*s[i].vol*(countt[i]*s[i].x - total[i] + (alltotal[i] - total[i] - s[i].x*(i-countt[i]) ) );            //cout<<ans<<endl;        }        printf("%I64d\n",ans);    }    return 0;}


0 0
原创粉丝点击