复习下树状数组

还是蛮有意思的一道题:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=501&page=show_problem&problem=4174

学到几点:

1、树状数组C[i]的构建,一则c[i]=s[i]-s[i-lowbit(i)];这是一直用的做法。如今学到一种新的,直接add(i,a[i]),(s[i]为a[1]到a[i]的和)

2、前缀和思想,树状数组的Sum本身就是基于前缀和的思想。本题把比某数小的数的个数,通过开大量空间+后缀数组,高效的统计出来比某数小的数的个数

3、事实上我认为通过这个题。能够做出来一种O(nlogn)的排序算法。当然不完好的地方就是仅仅能是整数了,可是应该能够用vector+map解决?

贴自己的代码先。,,由于后面的Lrj大牛的代码太简洁...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <functional> using namespace std; #define MAXN 20010
#define SIZE 100015 int a[MAXN],sma[SIZE],c[SIZE],s[SIZE],e[SIZE],tot[SIZE];
int n,mmax; int lowbit(int i)
{
return i & (-i);
} int sum(int i)
{
int ans=0;
for(;i>0;i-=lowbit(i))
ans+=c[i];
return ans;
} void add(int x, int d) {
while(x <= SIZE) {
c[x] += d; x += lowbit(x);
}
} void Init()
{
memset(c,0,sizeof(c));
memset(a,0,sizeof(a));
memset(sma,0,sizeof(sma));
memset(s,0,sizeof(s));
memset(e,0,sizeof(e));
memset(tot,0,sizeof(tot));
} int main()
{
//freopen("la4329.txt","r",stdin);
int t;
long long ans; scanf("%d",&t); while(t--)
{
mmax=0;
ans=0;
Init(); scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
mmax=max(mmax,a[i]);
add(a[i],1);
//c[i]=sum(a[i]-1);
e[a[i]]=1;
sma[a[i]]=sum(a[i]-1); }
memset(c,0,sizeof(c));
for(int i=1;i<=mmax;i++)
{
s[i] =s[i-1]+e[i];
c[i]=s[i]-s[i-lowbit(i)];
tot[i]=sum(i-1);
}
///////////////////////
//for(int i=1;i<=n;i++)
//{
// printf("sma[a[%d]] = %d tot(%d) = %d\n",i,sma[a[i]],a[i],tot[a[i]]);
//}
///////////////////////
for(int i=1;i<=n;i++)
{
int tmp = tot[a[i]]-sma[a[i]];/*a[i]之后比a[i]小的个数*/
ans+=(long long )tmp*(i-1-sma[a[i]])+(long long)sma[a[i]]*(n-i-tmp);
} printf("%lld\n",ans);
} return 0;
}

标程

// LA4329 Ping pong
// Rujia Liu
#include<cstdio>
#include<vector>
using namespace std; //inline int lowbit(int x) { return x&(x^(x-1)); }
inline int lowbit(int x) { return x&-x; } struct FenwickTree {
int n;
vector<int> C; void resize(int n) { this->n = n; C.resize(n); }
void clear() { fill(C.begin(), C.end(), 0); } // ¼ÆËãA[1]+A[2]+...+A[x] (x<=n)
int sum(int x) {
int ret = 0;
while(x > 0) {
ret += C[x]; x -= lowbit(x);
}
return ret;
} // A[x] += d (1<=x<=n)
void add(int x, int d) {
while(x <= n) {
C[x] += d; x += lowbit(x);
}
}
}; const int maxn = 20000 + 5;
int n, a[maxn], c[maxn], d[maxn];
FenwickTree f; int main() {
freopen("la4329.txt","r",stdin);
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
int maxa = 0;
for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); maxa = max(maxa, a[i]); }
f.resize(maxa);
f.clear();
for(int i = 1; i <= n; i++) {
f.add(a[i], 1);
c[i] = f.sum(a[i]-1);
}
f.clear();
for(int i = n; i >= 1; i--) {
f.add(a[i], 1);
d[i] = f.sum(a[i]-1);
} long long ans = 0;
for(int i = 1; i <= n; i++)
ans += (long long)c[i]*(n-i-d[i]) + (long long)(i-c[i]-1)*d[i];
printf("%lld\n", ans);
}
return 0;
}

树状数组 LA 4329 亚洲赛北京赛区题的更多相关文章

  1. HDU 6278 - Just h-index - [莫队算法+树状数组+二分][2018JSCPC江苏省赛C题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6278 Time Limit: 6000/3000 MS (Java/Others) Memory Li ...

  2. POJ 2155 Matrix 【二维树状数组】(二维单点查询经典题)

    <题目链接> 题目大意: 给出一个初始值全为0的矩阵,对其进行两个操作. 1.给出一个子矩阵的左上角和右上角坐标,这两个坐标所代表的矩阵内0变成1,1变成0. 2.查询某个坐标的点的值. ...

  3. 二维树状数组+差分【p4514】上帝造题的七分钟

    Description "第一分钟,X说,要有矩阵,于是便有了一个里面写满了\(0\)的\(n\times m\)矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为\((a,b)\),右 ...

  4. 树状数组+二分答案查询第k大的数 (团体程序设计天梯赛 L3-002. 堆栈)

    前提是数的范围较小 1 数据范围:O(n) 2 查第k大的数i:log(n)(树状数组查询小于等于i的数目)*log(n)(二分找到i) 3 添加:log(n) (树状数组) 4 删除:log(n) ...

  5. 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序

    3881: [Coci2015]Divljak Time Limit: 20 Sec  Memory Limit: 768 MBSubmit: 508  Solved: 158[Submit][Sta ...

  6. poj 2155 Matrix---树状数组套树状数组

    二维树状数组模版,唯一困难,看题!!(其实是我英语渣) Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 22098 ...

  7. poj2155 树状数组 Matrix

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 14826   Accepted: 5583 Descripti ...

  8. Why Did the Cow Cross the Road III(树状数组)

    Why Did the Cow Cross the Road III 时间限制: 1 Sec  内存限制: 128 MB提交: 65  解决: 28[提交][状态][讨论版] 题目描述 The lay ...

  9. [BZOJ4765]普通计算姬(分块+树状数组)

    4765: 普通计算姬 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 1725  Solved: 376[Submit][Status][Discus ...

随机推荐

  1. 搭建Samba共享服务器

    [root@localhost ~]# yum -y install samba         #安装Samba [root@localhost ~]# rpm -qa | grep samba  ...

  2. Android四大核心组件之Activity

    一.活动生命周期 二.生命周期执行介绍 当该页面(Activity)被启动时 会执行onCreate().onStart().onRestart()这三个方法, 只有当onRestart() 方法执行 ...

  3. matplotlib.pyplot.pcolormesh

     matplotlib.pyplot.pcolormesh(*args, alpha=None, norm=None, cmap=None, vmin=None, vmax=None, shading ...

  4. Uva 10305 拓扑排序

    题意: 给定n个点,与m条边, 给出他们的拓扑排序. 分析: 拓扑排序可以有两种做法, 第一种是dfs, 每次都找到某一个点的终点, 然后加入序列末尾, 正在访问的标记为-1, 访问过的标记为1, 未 ...

  5. spring+orm框架的兼容问题

    Springframework和Hibernate版本对应关系 org.springframework 3.0.x对应org.hibernate4.0.x版本 org.springframework ...

  6. python之字典 2014-4-5

    #字典:当索引不好用时1.字典 类似于php的关联数组 列表类似于索引数组 2.创建字典 phonebook={'alice':'2100','tom':'1900'} 键值之间用: 项之间用, 空字 ...

  7. msp430入门编程0

    msp430单片机最小系统 msp430入门学习 msp430入门编程

  8. android中后一个activity传值给前一个activity的实现

    前一个activity跳转到后一个activity设置code: Intent intent=new Intent(MainActivity.this,ActivityTwo.class); star ...

  9. codeforces Gym 100735 D、E、G、H、I

    http://codeforces.com/gym/100735 D题 直接暴力枚举 感觉这道题数据有点问题 为什么要先排下序才能过?不懂.. #include <stdio.h> #in ...

  10. hdu - 1195 Open the Lock (bfs) && hdu 1973 Prime Path (bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1195 这道题虽然只是从四个数到四个数,但是状态很多,开始一直不知道怎么下手,关键就是如何划分这些状态,确保每一个 ...