LA 4329(p197)----Ping pong

来源:互联网 发布:windows用cmd卸载软件 编辑:程序博客网 时间:2024/06/07 04:48
#include<bits/stdc++.h>#define debuusing namespace std;typedef long long LL;const int maxn=2*1e4+50;const int maxnn=1e5+50;int a[maxn];int n,l[maxn],maxx;int c[maxnn],r[maxn];inline int lowbit(int x){    return x&(-x);}void add(int x,int value){    for(int i=x; i<=maxx; i+=lowbit(i))        c[i]+=value;}int sum(int x){    int tmp=0;    for(int i=x; i; i-=lowbit(i))        tmp+=c[i];    return tmp;}int main(){#ifdef debug    freopen("in.in","r",stdin);#endif // debug    int t;    scanf("%d",&t);    while(t--)    {        maxx=0;        scanf("%d",&n);        for(int i=1; i<=n; i++)        {            scanf("%d",&a[i]);            maxx=max(maxx,a[i]);        }        LL ans=0;        memset(c,0,sizeof(c));        for(int i=1; i<=n; i++)        {            l[i]=sum(a[i]-1);            //cout<<i<<" "<<l[i]<<endl;            add(a[i],1);        }        memset(c,0,sizeof(c));        for(int i=n; i>=1; i--)        {            r[i]=sum(a[i]-1);            //cout<<i<<" "<<r[i]<<endl;            add(a[i],1);        }        for(int i=1; i<=n; i++)        {       //     cout<<i<<" "<<l[i]<<" "<<r[i]<<endl;            ans+=(long long)l[i]*(n-i-r[i])+(long long)r[i]*(i-1-l[i]);          //  cout<<ans<<endl;        }        printf("%lld\n",ans);    }    return 0;}

题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2330

题解:对于第i个人,设在1到i-1有l[i]个人小于他则有i-1-l[i]大于他,同理i+1到n有r[i]人小于他,则有n-i-r[i]人大于他。由加法原理和乘法原理,ans=sigma(l[i]*(n-i-r[i])+r[i]*(i-1-l[i]),所以只需求出l[i]与r[i]:从前到后扫描,c[x]==1表示x存在,则l[i]=sigma(c[1],c[2],。。。。,(c[a[i]-1)),每求一次后c[a[i]]置为1,r[i]同理。

0 0