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
",sum.val[0]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wangfang20/p/3301066.html