树状数组是一种能快速求出前n项和的数据结构,
例如:数组a0,a1,a2,a3,a4,a5....an。
sum(a[4])求的就是a0+a1+a2+a3+a4。
sum(a[n]-a[4])求的就是a5+...+an。
时间复杂度为o(nlogn)。
离散化 就是把原来的一组数变成另一组数,但是他们的相对大小不变。比如
把 4 6 8 9 2
变成 2 3 4 5 1
他们的逆序数不变
下面贴代码:
#include<iostream> #include<cmath> #include<string.h> #include<algorithm> using namespace std; const int MAXN=1000000+5; int b[MAXN],c[MAXN]; int n; struct node { int num,id; }a[MAXN]; bool cmp(node a,node b) { return(a.num<b.num); } void add(int i)//更新树状数组 { while(i<=n) { c[i]++; i+=i&(-i); } } int sum(int i)//树状数组求和 { int totle; while(i>0) { totle+=c[i]; i-=i&(-i); } return(totle); } int main() { int i,T; __int64 ans; scanf("%d",&T); while(T--) { scanf("%d",&n); memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); for(i=1;i<=n;i++) { scanf("%d",&a[i].num);//记录数据 a[i].id=i;//记录是第几个输入的 } sort(a+1,a+n+1,cmp); b[a[1].id]=1;//最小的那个变成1,次小的那个变成2,以此类推... for(i=2;i<=n;i++) { if(a[i].num!=a[i-1].num) b[a[i].id]=i; else b[a[i].id]=b[a[i-1].id]; } ans=0; for(i=1;i<=n;i++) { add(b[i]); ans+=(__int64)(sum(n)-sum(b[i]));//求到目前为止比这个数大的有多少个 } printf("%I64d\n",ans); } return(0); }
相关推荐
3. **离散化:** 将一个区间的值映射到一个连续的区间上,从而使得区间和的计算更为方便。这种技术在处理具有大量重复数值的问题时尤为有效。 4. **动态规划:** 在某些动态规划问题中,树状数组可以用来优化状态...
归并排序求逆序数 Pell方程 Catalan数,100以内 欧拉函数讲解 组合计数 组合数计算(double) 组合数计算(高精度) r-组合生成算法 r-排列生成算法 r-错位排列生成算法 图论 传递闭包 欧拉回路判定 有向图...
在解决逆序对问题时,首先需要对数列进行离散化处理,使得数据更加紧凑。通过树状数组的特性,每次插入一个数值时,可以统计比当前数值小的数的个数,进而快速计算出逆序对的总数。树状数组的关键操作包括update和...
9,树状数组模板 (求区间异或和,求逆序对) 扩展 10.区间不重复数字的和 (树状数组) 11.求k维空间中离所给点最近的m个点,并按顺序输出(KD树) 12.LCA (两个节点的公共父节点) 动态规划: 1.LIS (最长上升子序列) 2.有...
线段树是一种树形数据结构,每个节点代表一个区间,通常用于处理区间上的最大值、最小值、累加和等统计问题。线段树将区间分为左右两个子区间,这样可以通过递归的方式实现区间查询和更新。 2. **线段树的构造**:...
7.7 离散化 157 8.图论 158 8.0 2-SAT 158 8.2 寻找Euler回路 163 8.3 拓扑排序 163 8.4 差分约束系统 164 8.5 笛卡尔树 165 8.6 LCA和RMQ 167 8.7 割和桥 171 8.8 最小生成树(kruskal) 172 8.9 最短路径 173 8.10 ...
- **算法讨论**:考虑到数据范围较大,首先需要对输入的数值进行离散化处理,将其映射到较小的整数集合中。接着,使用四个树状数组分别记录每个数作为组合中特定位置(例如第一位、第二位等)时的情况数。对于每个数...
- **POJ 1151**:结合了线段树和离散化的技巧来求解矩形面积的并集。这需要对输入的坐标进行离散化处理,以减少空间复杂度,并使用线段树维护区间信息。 - **POJ 1177**:求解矩形周长的并集。此题与POJ 1151类似,...
- **归并排序求逆序数**:归并排序的过程中统计逆序数的方法。 - **日期计算**:涉及到日期和时间的处理,如计算两个日期之间的天数等。 - **KMP算法**:字符串匹配的经典算法。 - **字符串最小表示法**:将字符串...
5. 树形结构: - 遍历:前序、中序和后序遍历,以及层次遍历,理解树的结构和操作。 - 查找二叉树:二分查找树、AVL树、红黑树等,保持平衡以提高查找效率。 6. 字符串处理: - KMP算法:避免回溯,提高了模式...
- **扩展欧几里得算法**:不仅求出最大公约数,还能求出两个整数的互逆元,常用于模运算。 - **线性同余方程求解**:在数论中,解决形如ax ≡ b (mod m)的方程。 3. **排列组合**: - **排列生成**:算法用于...