poj 3378 二维树状数组

思路:直接用long long 保存会WA。用下高精度加法就行了。

#include<map>

#include<set>

#include<cmath>

#include<queue>

#include<cstdio>

#include<vector>

#include<string>

#include<iomanip>

#include<cstdlib>

#include<cstring>

#include<iostream>

#include<algorithm>

#define pb push_back

#define mp make_pair

#define Maxn 50010

#define Maxm 80002

#define LL __int64

#define Abs(x) ((x)>0?(x):(-x))

#define lson(x) (x<<1)

#define rson(x) (x<<1|1)

#define inf 100000

#define lowbit(x) (x&(-x))

#define mod 1000000000

using namespace std;

LL c[Maxn][5][2];

int n,num[Maxn];

struct OO{

    LL val[2];

};

struct PP{

    int val,i;

    int operator<(const PP &temp) const{

        return val<temp.val;

    }

}sorted[Maxn];

void update(int pos,int num,OO temp)

{

    while(pos<=n){

        c[pos][num][0]+=temp.val[0];

        c[pos][num][1]+=temp.val[1];

        c[pos][num][1]+=c[pos][num][0]/mod;

        c[pos][num][0]%=mod;

        pos+=lowbit(pos);

    }

}

OO Sum(int pos,int num)

{

    OO sum;

    sum.val[0]=sum.val[1]=0;

    while(pos){

        sum.val[0]+=c[pos][num][0];

        sum.val[1]+=c[pos][num][1];

        sum.val[1]+=sum.val[0]/mod;

        sum.val[0]%=mod;

        pos-=lowbit(pos);

    }

    return sum;

}

int main()

{

    int i,j;

    //freopen("ttt.txt","r",stdin);

    while(scanf("%d",&n)!=EOF){

        memset(c,0,sizeof(c));

        for(i=1;i<=n;i++){

            scanf("%d",num+i);

            sorted[i].val=num[i];

            sorted[i].i=i;

        }

        sort(sorted+1,sorted+1+n);

        int cnt=0;

        for(i=1;i<=n;i++){

            if(sorted[i].val!=sorted[i-1].val){

                num[sorted[i].i]=++cnt;

            }

            else num[sorted[i].i]=cnt;

        }

        OO sum;

        sum.val[0]=sum.val[1]=0;

        OO temp;

        for(i=1;i<=n;i++){

            temp=Sum(num[i]-1,4);

            sum.val[0]+=temp.val[0];

            sum.val[1]+=temp.val[1];

            sum.val[1]+=sum.val[0]/mod;

            sum.val[0]%=mod;

            temp.val[0]=1;

            temp.val[1]=0;

            update(num[i],1,temp);

            for(j=4;j>=2;j--)

            update(num[i],j,Sum(num[i]-1,j-1));

        }

        if(sum.val[1]){

            printf("%I64d",sum.val[1]);

            cout<<right<<setw(9)<<setfill('0')<<sum.val[0]<<endl;

        }

        else printf("%I64d\n",sum.val[0]);

    }

    return 0;

}

 

你可能感兴趣的:(树状数组)