首页 > 代码库 > hdu5147 (sequence 2) 树状数组
hdu5147 (sequence 2) 树状数组
1 #include <iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<vector> 6 #include<map> 7 using namespace std; 8 #define INF 0x7fffffff 9 #define MOD 100000000710 11 12 #define N 10001013 #define MAX 100010014 15 int C[MAX], S[MAX], b[N],d[N];16 long long f[N];17 long long total[N], ans;18 int num[N], T, s, t, i, j;19 20 int Lowbit(int x){21 return x&(x^(x-1));22 }23 24 void add(int pos,int num,int *P) {25 while(pos <= MAX) {26 P[pos] += num;27 pos += Lowbit(pos);28 }29 }30 31 int Sum(int end,int *P) {32 int cnt = 0;33 while(end > 0) {34 cnt += P[end];35 end -= Lowbit(end);36 }37 return cnt;38 }39 40 void init(){41 total[0] = 0;42 for(i = 1; i < N; ++i){43 total[i] = total[i-1] + i;44 }45 }46 47 int main() {48 //init();49 int t;50 cin>>t;51 52 while(t--) {53 54 scanf("%d",&T);55 56 memset(C,0,sizeof(C));57 memset(S,0,sizeof(S));58 memset(b,0,sizeof b);59 memset( d,0,sizeof d);60 memset(f,0,sizeof f);61 memset(num,0,sizeof num);62 //memset(num,0,sizeof(num));63 //memset(b,0,sizeof(b));64 //ans = 0;65 for(j = 0; j < T; j ++) {//因为第一个数前面比它小的数没有,所以j要从0开始66 scanf("%d",&num[j]);67 add(num[j]+1,1,C);68 b[j] = Sum(num[j], C);//Sum(num[j],C)求的就是小于s的个数,j - Sum(num[j],C)就是前j个数中大于num[j]的个数69 //printf("%d ",b[j]);70 }71 //printf("\n");72 //ans = 0;73 for(j = T-1; j > -1; --j){//反过来求第j个数右边中大于它的数的个数。74 add(num[j]+1 ,1, S);75 d[j] =T-1-j-Sum(num[j] ,S);//Sum(num[j],S)求的就是小于num[j]的个数76 //b[j] -= Sum(num[j]+1,S) - Sum(num[j],S)-1;77 //printf("%d ",b[j]);78 //ans += total[b[j]];79 }80 f[T-1]=0;81 for(int j=T-2;j>=0;j--)82 f[j]=d[j+1]+f[j+1];83 long long int res=0;84 for(int j=0;j<T;j++)85 res+=b[j]*f[j];86 cout<<res<<endl;87 88 }89 return 0;90 }91 92 代码君
理解有问题的话,先看树状数组求逆序数。
hdu5147 (sequence 2) 树状数组
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。