【uva】1428 - Ping pong(树状数组)
2014-07-30 00:06
387 查看
周五需要检测 树状数组以及线段树,这几天猛练一下,晚上看了一下二叉索引树,感觉还可以理解,不过A题的还是很有难度的。
题意给的很明显了,给一个位置i,求这个位置左边和右边比它小的数的个数(求出小的,求大的用减就可以了,因为a[i]的值都不重复.
我们从左往右检查,我们用一个数组vis[i]记录i值是否出现过(出现过为1,没出现为0),那么遍历到a[i]的时候我们只需要求 vis[1] + vis[2] + ……+vis[a[i] - 1],这样每次我们都需要花大量时间进行查询,其次,加入你使用C[i] 代表 vis[1] + vis[2] + …… +vis[i],那么,每次更行a[i],你都需要更新C[j] ( j > a[i]),非常耗费时间。因此使用上了树状数组。
如果进行查询操作,求vis[1] + vis[2] + vis[x];
如果进行插入,该表vis的值
此外,lowbit(x) = x & -x;
这题经过计算数据范围需要使用long long 表示
题意给的很明显了,给一个位置i,求这个位置左边和右边比它小的数的个数(求出小的,求大的用减就可以了,因为a[i]的值都不重复.
我们从左往右检查,我们用一个数组vis[i]记录i值是否出现过(出现过为1,没出现为0),那么遍历到a[i]的时候我们只需要求 vis[1] + vis[2] + ……+vis[a[i] - 1],这样每次我们都需要花大量时间进行查询,其次,加入你使用C[i] 代表 vis[1] + vis[2] + …… +vis[i],那么,每次更行a[i],你都需要更新C[j] ( j > a[i]),非常耗费时间。因此使用上了树状数组。
如果进行查询操作,求vis[1] + vis[2] + vis[x];
int Sum(int x){ /*求和的话向左边走*/ int ans = 0; while(x > 0){ ans += C[x]; x -= lowbit(x); } return ans; }
如果进行插入,该表vis的值
int Add(int x,int d){ while(x < MAXD){ C[x] += d; x += lowbit(x); } }
此外,lowbit(x) = x & -x;
这题经过计算数据范围需要使用long long 表示
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define MAXD 100000 + 10
typedef long long LL;
int array[MAXD];
int C[MAXD];
int lowbit(int x){
return x & -x;
}
int Sum(int x){ /*求和的话向左边走*/ int ans = 0; while(x > 0){ ans += C[x]; x -= lowbit(x); } return ans; }
int Add(int x,int d){ while(x < MAXD){ C[x] += d; x += lowbit(x); } }
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
int vis[MAXD]; /*记录i是否存在*/
int c[MAXD],d[MAXD];
memset(vis,0,sizeof(vis));
memset(C,0,sizeof(C));
scanf("%d",&n);
for(int i = 1 ; i <= n ; i++)
scanf("%d",&array[i]);
for(int i = 1 ; i <= n ; i++){ /*左边比a[i]小的数个数*/
int t = array[i];
if(!vis[t]){
vis[t] = 1;
Add(t,1);
}
c[i] = Sum(t) - 1;
}
memset(C,0,sizeof(C));
memset(vis,0,sizeof(vis));
for(int i = n ; i >= 1; i--){ /*右边比a[i]小的数个数*/
int t = array[i];
if(!vis[t]){
vis[t] = 1;
Add(t,1);
}
d[i] = Sum(t) - 1;
}
LL ans = 0;
for(int i = 1 ; i <= n ; i++){
ans = ans + c[i] * (n - i - d[i]) + (i - 1 - c[i]) * d[i];
}
printf("%lld\n",ans);
}
return 0;
}
相关文章推荐
- uva 1428 - Ping pong(树状数组)
- Beijing 2008 / UVa 1428 / POJ 3928 / HDU 2492 Ping pong (树状数组)
- UVA 1428 Ping Pong(树状数组)
- uva 1428 - Ping pong(树状数组,4级)
- uva 1428 - Ping pong(树状数组,4级)
- UVA 1428 - Ping pong(树状数组)
- UVA1428 Ping pong(树状数组)
- uva 1428 Ping pong (树状数组)
- UVA-1428 - Ping pong(树状数组)
- UVA1428 - Ping pong(树状数组)
- UVA1428 Ping pong(树状数组)
- UVA1428 Ping pong(树状数组)
- uva 1428 - Ping pong (树状数组的应用)
- UVA 1428 - Ping pong(树状数组)
- uva 1428 - Ping pong(树状数组)
- [树状数组]Ping Pong, Beijing 2008, Uva1428
- Uva 1428 Ping pong (树状数组,Fenwick树)
- UVA 1428 - Ping pong(树状数组)
- UVa:1428 Ping pong (树状数组)
- uvalive 4329 Ping pong (树状数组)