站队(test05)

来源:互联网 发布:2016淘宝刷单被降权 编辑:程序博客网 时间:2024/05/16 01:19

Problem:
给定一个长度为n的队列,求它是第几种站队方式(从矮到高认为是第一种,从高到矮认为是最后一种)
1<n<105
100.0000<ai<200.0000查找很不优雅,自然我们想到用数据结构(树状数组,线段树,平衡树)进行优化。查找复杂度降为log()级别。
下面是代码(树状数组):

#include <stdio.h>#include <algorithm>using namespace std;typedef long long LL;#define mod 1000000007#define lowbit(x) ((x)&(-x))LL n,t[100001],ans,fac[100001],res;struct data{    double val;    int pos,id;}person[100001];bool cmp(data x,data y){    return x.val<y.val;}bool cmp1(data x,data y){    return x.pos<y.pos;}void Update(int x,int c){    for(int i=x; i<=100000; i+=lowbit(i))        t[i]+=c;}LL getpos(LL x){    LL pos=0;    for(int i=x; i; i-=lowbit(i))        pos+=t[i];    return pos;}LL getans(LL x){    LL ans=(getpos(person[x].id)-1)%mod*fac[n-x]%mod;    return ans;}int main(){    scanf("%I64d",&n);    for(int i=1; i<=n; i++)    {        scanf("%lf",&person[i].val);        person[i].pos=i;    }    fac[0]=1;    for(int i=1; i<=n; i++)        fac[i]=fac[i-1]%mod*i%mod;    sort(person+1,person+n+1,cmp);    for(int i=1; i<=n; i++)        person[i].id=i;    sort(person+1,person+n+1,cmp1);    for(int i=1; i<=n; i++)        Update(i,1);    for(int i=1; i<=n; i++)    {        (res+=getans(i))%=mod;        Update(person[i].id,-1);    }    printf("%I64d",res+1);    return 0;} 
0 0
原创粉丝点击