关于“快读”和“-o2”“-o3”优化
快读
"快读"是一种优化输入操作的技巧,旨在提高输入效率。在C++中,通常使用scanf
或cin
进行输入,但对于大规模的输入数据,这些方法可能会导致运行时间过长。快读是一种替代方法,它使用getchar
函数来逐字符读取输入,并将字符转换为对应的数字。
快读的基本原理是利用getchar
函数逐字符读取输入,并通过一系列操作将字符转换为整数。这样可以避免使用格式化输入函数如scanf
或cin
,从而提高输入效率。
以下是一个使用快读进行输入的示例代码:
int readInt() {
int x = 0, y = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')
y = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * y;
}
上述代码定义了一个readInt
函数,用于读取一个整数。它通过逐字符读取输入,并将字符转换为整数,然后返回该整数值。
快读的优势在于它可以显著提高输入效率,特别是在面对大量输入数据的情况下。然而,需要注意的是,快读对于输入的格式要求较高,需要保证输入的数据符合预期的格式,否则可能会导致错误的结果。
需要注意的是,由于快读是一种非标准的输入方式,并不是C++标准库的一部分,因此在一些在线评测系统或特定的环境中,可能会出现不兼容的情况。在这些情况下,最好使用标准的输入函数如scanf
或cin
来进行输入操作。
nefu暴力出奇迹
Problem:D
Time Limit:1000ms
Memory Limit:65535K
Description
给你一个长度为n的序列A; 定义f(l,r)=A(l)+A(l+1)+...+A(r); 询问m次,每次询问一个x,请你计算 请求出所有满足 r−l+1≥x区间 [l,r]中最大的 f(l,r)。
Input
输入n,m; 然后n个数代表A(i); 然后是m个数x;
Output
输出m行,每行输出最大的f(l,r);
Sample Input
5 5 1 2 3 4 5 1 2 3 4 5
Sample Output
15 15 15 15 15
Hint
1≤x≤n≤1e4,0≤m≤1e5,∣Ai∣≤1e4.
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
int n, m, a[1000010], ans[10000010];
int x;
int read()
{
int x = 0, y = 1;
char c = getchar();
while (c > '9' || c < '0')
{
if (c == '-')
y = -1;
c = getchar();
}
while (c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
return x * y;
}
int main()
{
n = read();
m = read();
int i, j;
for (i = 1; i <= n; i++)
a[i] = read();
for (i = 1; i <= n; i++)
a[i] += a[i - 1];
memset(ans, -127, sizeof(ans));
for (x = 1; x <= n; x++)
for (i = 1; i + x - 1 <= n; i++)
{
ans[x] = max(ans[x], a[i + x - 1] - a[i - 1]);
}
for (i = 1; i <= n; i++)
{
int mx = -1e9;
for (j = i; j <= n; j++)
{
mx = max(mx, ans[j]);
}
ans[i] = mx;
}
while (m--)
{
x = read();
printf("%d\n", ans[x]);
}
}
“-o2”“-o3”优化
nefu小清新切绳子-二分
Problem:D
Time Limit:1000ms
Memory Limit:65535K
Description
小清新又双叒叕被WA疯了,原来是被double类型的精度给坑了,但题目那么好,怎么能不安利一波呢=。= 于是他悄悄地修改了下数据,安利给那些可爱的小可爱们(没错( ̄▽ ̄)~*),就是屏幕前的你们。 有N条绳子,它们的长度分别为Li。如果从它们中切割出K条长度相同的绳子,这K条绳子每条最长能有多长?
Input
题目比较卡时间,请使用快读读入,并尽可能减少你的常数,可以考虑开启O2、O3等优化 多组输入! 第一行两个整数N和K,接下来一行N个整数,描述了每条绳子的长度Li ,以空格隔开。 对于100%的数据 1<=Li<10,000,000 , 1<=n,k<=10000
Output
切割后每条绳子的最大长度(一个整数)
Sample Input
4 11 802 743 457 539
Sample Output
200
Hint
二分
Source
小清新(改编自洛谷)
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
typedef long long LL;
const int N = 1e4 + 5;
int arr[N];
int n, k;
int fun(int mid) {
int sum = 0, num = 1;
for (int i = 1; i <= n; i++) {
sum += arr[i] / mid;
if (sum >= k)
return 1;
}
return 0;
}
int readInt() {
int x = 0, y = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-')
y = -1;
c = getchar();
}
while (c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * y;
}
int main() {
while (scanf("%d%d", &n, &k) != EOF) {
int l = 0, r = 0;
for (int i = 1; i <= n; i++) {
arr[i] = readInt();
r = max(r, arr[i]);
}
int mid, ans = 0;
while (r >= l) {
mid = l + (r - l) / 2;
if (mid == 0)
break;
else if (fun(mid)) {
ans = mid;
l = mid + 1;
}
else
r = mid - 1;
}
printf("%d\n", ans);
}
return 0;
}
-O2
和-O3
是编译器的优化选项,用于告诉编译器在生成可执行程序时进行不同级别的优化。这些选项会使编译器尝试在代码生成过程中应用各种优化技术,以改善程序的性能和执行速度。
-O2
表示进行中级优化,而-O3
表示进行更高级别的优化。这两个选项都是在编译时指定的参数,可以根据需要选择适当的优化级别。
以下是对-O2
和-O3
优化选项的简要说明:
-
-O2
优化选项:-O2
会启用一系列的编译器优化技术,包括循环展开、函数内联、常量传播、代码移动等。- 这些优化旨在提高程序的执行速度和整体性能,同时保持较快的编译速度。
-O2
相对较保守,可以提供显著的性能改进,而且通常不会引入太多的编译时间延迟。
-
-O3
优化选项:-O3
是更高级别的优化选项,它包含了-O2
中的所有优化,同时引入了更多的高级优化技术。- 这些高级优化包括函数内存局部性改善、自动向量化、循环变量展开等。
-O3
可以进一步提高程序的执行速度和性能,但相应地也会增加编译时间。
需要注意的是,使用更高级别的优化选项会增加编译时间,并且可能会导致一些不可预测的行为。在某些情况下,某些特定的优化可能会导致代码出现错误或与预期结果不一致。因此,在选择优化选项时,需要权衡编译时间和优化带来的性能提升,并进行充分的测试和验证。
一般来说,建议在开发和调试阶段使用较低级别的优化选项(如-O1
或-O2
),以便更容易进行代码调试和分析。而在发布或部署阶段,可以选择更高级别的优化选项(如-O2
或-O3
),以获得更好的性能和执行速度。