您的位置:首页 > 其它

poj 3378 二维树状数组

2013-09-04 15:06 183 查看
思路:直接用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: