数据结构(荣誉)实验五 树状数组

简介: 数据结构(荣誉)实验五 树状数组

1. 树状数组操作


题目描述


给你n个数,创建一个树状数组,并执行相应操作,按格式要求输出操作结果。执行的操作有以下两种形式:


C i dt ,表示更新A[i],使得A[i]=A[i]+dt,其中1<=i<=n;


Q i j ,表示询问区间和,即A[i]+A[i+1]+…+A[j]的值,其中1<=i<=j<=n。


输入


第一行一个正整数n(1<=n<=10000),代表数据个数。


接下来一行是n个数据。


接下来一行一个正整数m,代表m个操作。


接下来m行,每行一个操作,格式如上所述。


输出


第一行输出创建后的树状数组,数据之间以空格分隔。


接下来m行,输出m个操作结果:对每个“C i dt ”操作,输出更新后的树状数组,数据间以空格分隔;对每个“Q i j ”操作,输出一个数值。


样例输入


10

1 3 2 6 7 -2 5 8 4 10

5

Q 1 10

C 2 4

Q 2 6

C 6 -3

Q 6 6


样例输出


1 4 2 12 7 5 5 30 4 14

44

1 8 2 16 7 5 5 34 4 14

20

1 8 2 16 7 2 5 31 4 14

-5


题解

#include<iostream>
using namespace std;
int treeNode[10005] = {0};
int length;
int lowbit(int num) {
    return num & (-num);
}
int query(int index) {
    int ans = 0;
    while (index > 0) {
        ans += treeNode[index];
        index -= lowbit(index);
    }
    return ans;
}
void change(int index, int value) {
    while (index <= length) {
        treeNode[index] += value;
        index += lowbit(index);
    }
}
void display() {
    cout << treeNode[1];
    for (int i = 2; i <= length; i++) {
        cout << " " << treeNode[i];
    }
    cout << endl;
}
int main() {
    cin >> length;
    int *num = new int[length + 1];
    for (int i = 1; i <= length; i++) {
        num[i] = 0;
        treeNode[i] = 0;
    }
    for (int i = 1; i <= length; i++) {
        cin >> num[i];
        change(i, num[i]);
    }
    display();
    int n;
    char ope;
    cin >> n;
    while (n--) {
        cin >> ope;
        if (ope == 'Q') {
            int startIndex, endIndex;
            cin >> startIndex >> endIndex;
            cout << query(endIndex) - query(startIndex - 1) << endl;
        } else {
            int index, value;
            cin >> index >> value;
            change(index, value);
            display();
        }
    }
    return 0;
}

2. 逆序对


题目描述


给你n个数,每个数a[i]都是不超过1 0 9 10^910

9

的非负整数。求其中逆序对的个数,即所有这样的数对(i , j )满足1<=i<j<=n且a[i]>a[j]。要求用树状数组的相关操作完成题目。


输入


第一行一个正数n(1<=n<=100000),表示数据的个数。


接下来一行是n个整数。


输出


第一行一个整数m,代表逆序对的个数。


样例输入


5

4 7 2 10 9


样例输出


3


题解

#include<iostream>
using namespace std;
int treeNode[10005] = {0};
int length;
int lowbit(int num) {
    return num & (-num);
}
int query(int index) {
    int ans = 0;
    while (index > 0) {
        ans += treeNode[index];
        index -= lowbit(index);
    }
    return ans;
}
void change(int index, int value) {
    while (index <= length) {
        treeNode[index] += value;
        index += lowbit(index);
    }
}
void display() {
    cout << treeNode[1];
    for (int i = 2; i <= length; i++) {
        cout << " " << treeNode[i];
    }
    cout << endl;
}
int getValue(int num) {
    return query(num) - query(num - 1);
}
int main() {
    cin >> length;
    int *num = new int[length + 1];
    for (int i = 1; i <= length; i++) {
        num[i] = 0;
        treeNode[i] = 0;
    }
    for (int i = 1; i <= length; i++) {
        cin >> num[i];
        change(i, num[i]);
    }
    int count = 0;
    for (int i = 1; i <= length; i++) {
        for (int j = i + 1; j <= length; j++) {
            if (getValue(i) > getValue(j)) {
                count++;
            }
        }
    }
    cout << count << endl;
    return 0;
}


3.矩阵操作


题目描述


给定一个n✖n的矩阵A,其中每个元素不是0就是1。A[i,j]表示在第i行、第j列的数,初始时,A[i,j]=0 (1<=i,j<=n)。


我们可以按照如下方式改变矩阵:给定一个左上角在(x1,y1)、右下角在(x2,y2)的矩形,通过使用“not”操作改变这个矩形内的所有元素值(元素0变成1,元素1变成0)。为了维护矩阵的信息,你需要写个程序来接收并且执行以下两个操作:


(1)C x1 y1 x2 y2 (1<=x1<=x2<=n, 1<=y1<=y2<=n),表示更新操作,将改变左上角为(x1,y1)、右下角为(x2,y2)的矩形区域内的数据值,若元素值为0,则变成1;若元素值为1,则变成0。


(2)Q x y (1<=x,y<=n),表示询问操作,询问A[x,y]的值。


输入


第一行两个整数n和T(2<=n<=1000, 1<=T<=50000),分别代表方阵大小和操作数。


接下来T行,每行包含一个操作,以“C x1 y1 x2 y2”或者“Q x y”的形式给出,具体描述如上。


输出


对每个询问操作,输出一行一个整数,表示相应矩阵元素的值。


样例输入


2 10

C 2 1 2 2

Q 2 2

C 2 1 2 1

Q 1 1

C 1 1 2 1

C 1 2 1 2

C 1 1 2 2

Q 1 1

C 1 1 2 1

Q 2 1


样例输出


1

0

0

1


提示


一般的,树状数组是处理查询一个区间、修改一个点,而本题是要处理查询一个点、修改一个区间。在修改区间的时候,可以考虑容斥原理。修改时加一个tag,修改偶数次相当于未修改。


题解

#include<iostream>
using namespace std;
int treeNode[1005][1005] = {0};
int length;
int lowbit(int num) {
    return num & (-num);
}
int query(int index) {
    int ans = 0;
    while (index > 0) {
        ans += treeNode[index][index];
        index -= lowbit(index);
    }
    return ans;
}
void change(int index, int value) {
    while (index <= length) {
        treeNode[index][index] += value;
        index += lowbit(index);
    }
}
void display() {
    cout << treeNode[1];
    for (int i = 2; i <= length; i++) {
        cout << " " << treeNode[i];
    }
    cout << endl;
}
int main() {
    cin >> length;
    int n;
    cin >> n;
    for (int i = 1; i <= length; i++) {
        for (int j = i; j <= length; j++) {
            treeNode[i][j] = 0;
        }
    }
    while (n--) {
        string ope;
        cin >> ope;
        if (ope == "C") {
            int x1, y1, x2, y2;
            cin >> x1 >> y1 >> x2 >> y2;
            for (int i = x1; i <= x2; i++) {
                for (int j = y1; j <= y2; j++) {
                    if (treeNode[i][j] == 0) {
                        treeNode[i][j] = 1;
                    } else {
                        treeNode[i][j] = 0;
                    }
                }
            }
        }
        if (ope == "Q") {
            int x, y;
            cin >> x >> y;
            cout << treeNode[x][y] << endl;
        }
    }
    return 0;
}
相关文章
|
7月前
|
机器学习/深度学习 算法 搜索推荐
数据结构实验之排序六:希尔排序
数据结构实验之排序六:希尔排序
|
29天前
|
存储 算法 编译器
数据结构实验之矩阵的运算器(二维数组)
本实验旨在通过团队合作,掌握数组和矩阵相关运算的代码实现,包括矩阵的加减、数乘、转置、乘法、n次方及行列式的计算。实验过程中,成员们需分工协作,解决编程难题,最终实现一个功能完备的矩阵计算器。通过本实验,不仅锻炼了编程能力,还加深了对数学概念的理解,同时培养了团队合作精神。
56 4
|
29天前
数据结构实验之串模式匹配问题
本实验旨在掌握串模式匹配技术,通过创建文本文件、实现单词计数与定位功能,最终构建一个包含文件建立、单词统计与定位、程序退出等选项的主菜单,以增强对字符串处理的理解与应用能力。
44 4
|
29天前
|
算法
数据结构实验之最长公共子序列
本实验旨在通过编程实践帮助学生理解串的基本概念及求解最长公共子序列的算法。实验内容包括使用动态规划方法设计并实现算法,以找出给定两序列的最大公共子序列。示例代码展示了如何通过构建状态矩阵和回溯路径来找到解决方案。实验总结指出,`memset()`函数用于内存初始化,且对于特定输入,程序能正确输出最长公共子序列之一。
51 4
|
29天前
|
算法
数据结构实验之操作系统打印机管理器问题
本实验旨在通过实现操作系统中的打印机管理器问题,掌握队列的基本操作如入队、出队等,利用队列的先进先出特性解决先申请先打印的问题。实验包括队列的初始化、入队、出队、打印队列内容等功能,并通过菜单式界面进行交互。实验结果显示基本功能可正常执行,但在连续操作时存在执行失败的情况,需进一步优化。
41 4
|
29天前
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
53 4
|
29天前
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
81 4
|
29天前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
51 4
|
6月前
|
存储 算法 数据安全/隐私保护
【Python学习篇】Python实验小练习——高级数据结构(五)
【Python学习篇】Python实验小练习——高级数据结构(五)
71 1
|
6月前
|
存储 算法 数据挖掘
数据结构实验||约瑟夫环
数据结构实验||约瑟夫环