rexaron

导航

算法小笔记0328

1

ios::sync_with_stdio(0);

ios::sync_with_stdio(false); 是 C++ 中用于关闭 C++ 输入输出流(iostream)与 C 输入输出库(stdio)同步的语句。默认情况下,C++ 的流库与 C 的stdio库是同步的,这意味着你可以混用 cin, coutscanf, printf 等而不会出现问题。但是这种同步会导致性能下降,因为每个流库的操作都需要检查stdio库的状态。
当你设置 std::ios_base::sync_with_stdio(false); 时,你告诉 C++ 不必再与stdio库同步。这将提高输入输出操作的效率,特别是当你在程序中使用大量的 I/O 操作时。但是,这样做之后你就不能再保证 cin, cout 和 C 的 scanf, printf 混用时的正确性了。通常,在竞赛编程或者需要高性能 I/O 的场合,程序员会关闭同步,并使用 cin.tie(0); 进一步提高性能,因为这样可以解除 cincout 之间的绑定,使得 cincout 可以独立地、不按顺序地缓冲它们的 I/O 操作。
使用这个语句的典型场景是在程序的开头:这样做之后,你应该只使用 cincout 或者只使用 scanfprintf,避免混用,以防止未定义行为。

2

cin.tie(0); cout.tie(0);

在 C++ 中,cin.tie()cout.tie() 是与流对象的绑定相关的函数。默认情况下,cincout 是绑定的,这意味着当 cincout 同时用于输入和输出时,它们会保证输出的顺序与输入的顺序一致。这种绑定是为了让输出与输入保持同步,比如在交互式程序中,你希望在读取输入之前先看到所有的输出。
cin.tie(nullptr)cin.tie(0) 的作用是取消 cincout 之间的绑定。这样,cin 的输入缓冲区和 cout 的输出缓冲区就可以独立地运作,不再需要等待对方。这通常可以提高 I/O 效率,特别是在进行大量 I/O 操作时。
同样地,cout.tie(nullptr)cout.tie(0) 也可以用来取消 cout 的当前绑定。但是,通常你不需要这样做,因为 cout 默认就是与 cin 绑定的,而且取消 cin 的绑定通常也就意味着 cout 的绑定也被取消了。

3

priority_queue<int,vector<int>,greater<int>> h[100010]; //为每一家店创造一个优先队列(小顶对)

在 C++ 中,priority_queue<int, vector<int>, greater<int>> h[100010]; 声明了一个包含 100010 个优先队列的数组 h。每个优先队列都是使用 int 作为元素类型,vector<int> 作为底层容器,greater<int> 作为比较器的。
priority_queue 是 C++ 标准库中的一个容器适配器,它提供常数时间内的最大元素提取操作,即每次调用 pop 时移除的是队列中最大的元素,每次调用 top 时访问的是队列中最大的元素。默认情况下,priority_queue 是一个大顶堆,但是在这个声明中,通过使用 greater<int> 作为比较器,它被转换为一个一个小顶堆,即每次移除和访问的是队列中最小的元素。
vector<int> 是用于存储优先队列元素的底层容器,而 greater<int> 是一个函数对象,它定义了元素之间的比较方式。在这个例子中,greater<int> 会使得优先队列按照升序排列,即最小的元素在顶部。
这个声明的数组大小为 100010,这意味着你可以使用 h[0]h[100009] 来访问数组中的每个优先队列。这在处理一些需要多个优先队列的问题时非常有用,例如在图论中的 Dijkstra 算法或者在某些数据结构中的多路归并问题。

4

sort(a+1, a+1+m, cmp);

在 C++ 中,sort(a+1, a+1+m, cmp) 是对标准库函数 std::sort 的一个调用,用于对数组 a 从第 a+1 个元素开始到第 a+m 个元素结束的子数组进行排序。这里的 cmp 是一个比较函数,用于定义排序的顺序。
std::sort 是 C++ 标准库中的算法,它位于 <algorithm> 头文件中。该函数使用快速排序算法的一个变体,其平均和最坏情况时间复杂度都是 O(n log n),其中 n 是要排序的元素数量。
这里的参数解释如下:

  • a+1:指向要排序的子数组的起始元素的指针。由于数组索引是从 0 开始的,a+1 表示数组 a 的第二个元素。
  • a+1+m:指向要排序的子数组的结束位置的后一个位置的指针。由于 sort 的第二个参数是结束位置的后一个位置,所以 a+1+m 表示从 a+1 开始的第 m 个元素之后的位置。
  • cmp:比较函数,用于确定排序的顺序。这个函数应该接受两个参数,并返回一个布尔值,表示第一个参数是否小于第二个参数。如果 cmp 返回 true,则第一个参数会被放在第二个参数前面;如果返回 false,则第一个参数会被放在第二个参数后面。
    下面是一个使用 std::sort 的例子,包括一个简单的比较函数 cmp
#include <iostream>
#include <algorithm>
// 比较函数,按升序排序
bool cmp(int a, int b) {
    return a < b;
}
int main() {
    int a[] = {4, 2, 5, 1, 3};
    int m = 3; // 假设我们只想对数组的前 3 个元素进行排序
    // 对数组的前 m 个元素进行排序
    std::sort(a + 1, a + 1 + m, cmp);
    // 输出排序后的数组
    for (int i = 0; i < 5; ++i) {
        std::cout << a[i] << ' ';
    }
    std::cout << std::endl;
    return 0;
}

在这个例子中,数组 a 的第二个到第四个元素(索引为 1 到 3)会被排序,而第一个和最后一个元素(索引为 0 和 4)不会被排序。排序后的输出将是 4 1 2 5 3

5

bool operator < (const order &A)const{
        return ti < A.ti;
    }

在 C++ 中,operator< 是一个重载运算符函数,用于比较两个对象的大小关系。在您提供的代码片段中,operator< 被重载用于比较两个 order 类型的对象。这个运算符函数定义在 order 类的内部,并且被声明为 const 成员函数,这意味着它不会修改调用它的对象。
这个重载的 operator< 函数接受一个类型为 const order& 的参数 A,表示要比较的另一个 order 对象。在这个函数中,tiorder 类的一个成员变量,用于确定两个 order 对象的顺序。如果当前对象的 ti 成员变量小于参数 Ati 成员变量,函数返回 true;否则返回 false
这种重载通常用于自定义类型,以便在标准库算法(如 sortpriority_queue 等)中使用自定义比较逻辑。例如,如果您有一个 order 类型的对象数组,并且想要根据 ti 成员变量对数组进行排序,您可以这样做:

#include <iostream>
#include <vector>
#include <algorithm>
class order {
public:
    int ti;
    // 构造函数
    order(int t) : ti(t) {}
    // 重载 operator<
    bool operator<(const order &A) const {
        return ti < A.ti;
    }
};
int main() {
    vector<order> orders = {order(3), order(1), order(2)};
    // 使用 sort 对 orders 数组进行排序
    sort(orders.begin(), orders.end());
    // 输出排序后的 orders
    for (const auto &o : orders) {
        cout << o.ti << ' ';
    }
    cout << std::endl;
    return 0;
}

在这个例子中,sort 函数会使用 order 类中定义的 operator< 来比较 order 对象,并按照 ti 成员变量的值对它们进行升序排序。输出将是 1 2 3

6

memset(have,0,sizeof(have));

在 C++ 中,memset 是一个常用的库函数,用于将内存中的某一块区域全部设置为某个特定的值。它定义在 <cstring> 头文件中(在 C 语言中是 <string.h>)。memset 的原型如下:

void *memset(void *s, int c, size_t n);
  • s:指向要填充的内存块的指针。
  • c:要设置的值,该值以整数形式传递,但是函数会将该整数转换为无符号字符(unsigned char)后再填充内存。
  • n:要填充的字节数。
    在您提供的代码片段中,memset(have, 0, sizeof(have)); 的作用是将 have 所指向的内存区域中的前 sizeof(have) 个字节全部设置为 0。这通常用于初始化数组或结构体的内存,确保所有位都被清零。
    例如,如果您有一个整数数组 int have[100];,那么 memset(have, 0, sizeof(have)); 将会把数组 have 中的所有元素都初始化为 0。
    请注意,memset 应该用于对字节进行操作的情景,如果您想要将一个结构体或对象的内存全部设置为 0,这可能是一个合适的选择。但是,如果您想要将数组中的每个元素初始化为特定的值,而且这个值不是 0 或 -1,那么您应该使用其他方法,比如循环初始化或使用标准库函数 std::fillstd::fill_n。这是因为 memset 只能设置内存为 0 或 -1(由于填充的是字节,而不是整数或浮点数)。

posted on 2024-03-28 11:16  rexrex  阅读(12)  评论(0编辑  收藏  举报