【发布时间】:2017-06-04 13:03:01
【问题描述】:
在 C++ 中获取输入输出时,我只使用了 scanf/printf 和 cin/cout。现在我最近遇到了this 代码以一种奇怪的方式进行 I/O。
另外请注意,这种 I/O 方法会导致代码运行得非常快,因为此代码使用与大多数其他代码几乎相同的算法,但它的执行时间要短得多。为什么这个 I/O 如此之快?一般来说它是如何工作的?
编辑:代码
#include <bits/stdtr1c++.h>
#define MAXN 200010
#define MAXQ 200010
#define MAXV 1000010
#define clr(ar) memset(ar, 0, sizeof(ar))
#define read() freopen("lol.txt", "r", stdin)
using namespace std;
const int block_size = 633;
long long res, out[MAXQ]; int n, q, ar[MAXN], val[MAXN], freq[MAXV];
namespace fastio{
int ptr, ye;
char temp[25], str[8333667], out[8333669];
void init(){
ptr = 0, ye = 0;
fread(str, 1, 8333667, stdin);
}
inline int number(){
int i, j, val = 0;
while (str[ptr] < 45 || str[ptr] > 57) ptr++;
while (str[ptr] > 47 && str[ptr] < 58) val = (val * 10) + (str[ptr++] - 48);
return val;
}
inline void convert(long long x){
int i, d = 0;
for (; ;){
temp[++d] = (x % 10) + 48;
x /= 10;
if (!x) break;
}
for (i = d; i; i--) out[ye++] = temp[i];
out[ye++] = 10;
}
inline void print(){
fwrite(out, 1, ye, stdout);
} }
struct query{
int l, r, d, i;
inline query() {}
inline query(int a, int b, int c){
i = c;
l = a, r = b, d = l / block_size;
}
inline bool operator < (const query& other) const{
if (d != other.d) return (d < other.d);
return ((d & 1) ? (r < other.r) : (r > other.r));
} } Q[MAXQ];
void compress(int n, int* in, int* out){
unordered_map <int, int> mp;
for (int i = 0; i < n; i++) out[i] = mp.emplace(in[i], mp.size()).first->second; }
inline void insert(int i){
res += (long long)val[i] * (1 + 2 * freq[ar[i]]++); }
inline void erase(int i){
res -= (long long)val[i] * (1 + 2 * --freq[ar[i]]); }
inline void run(){
sort(Q, Q + q);
int i, l, r, a = 0, b = 0;
for (res = 0, i = 0; i < q; i++){
l = Q[i].l, r = Q[i].r;
while (a > l) insert(--a);
while (b <= r) insert(b++);
while (a < l) erase(a++);
while (b > (r + 1)) erase(--b);
out[Q[i].i] = res;
}
for (i = 0; i < q; i++) fastio::convert(out[i]); }
int main(){
fastio::init();
int n, i, j, k, a, b;
n = fastio::number();
q = fastio::number();
for (i = 0; i < n; i++) val[i] = fastio::number();
compress(n, val, ar);
for (i = 0; i < q; i++){
a = fastio::number();
b = fastio::number();
Q[i] = query(a - 1, b - 1, i);
}
run();
fastio::print();
return 0; }
【问题讨论】:
-
请自行提出问题。也就是说,它不应该依赖于本网站之外的内容。在问题中发布相关代码。
-
您是否在问为什么这个
char str[8333667]; fread(str, 1, 8333667, stdin);会比其他方法更快?请将该代码的相关部分添加到您的问题中。 -
此代码使用特定于任务的解析,比 scanf 或 c++ iostream cin 更快,因为此代码仅解析许多可能的数字格式的一小部分,并且不检查输入是否有错误。此代码中的逻辑更少,分支更少,因此速度更快。并且只有 1 个系统调用可以一次读取完整文件,并将 fread 读取到内存中,没有很多系统调用和小 4KB 或类似经典 scanf/cin 的缓冲区。
-
@akka 检查错误?比如文件打不开怎么办?还是从文件中读取错误?或者如果解析内容时出错?需要检查和处理这些(以及更多)条件。