This commit is contained in:
2024-01-29 15:38:09 +08:00
parent 7390900ee6
commit bfcbb1996a
5 changed files with 1094 additions and 0 deletions

205
ACMOJ-1811.cpp Normal file
View File

@ -0,0 +1,205 @@
#include <cstdio>
#define unlikely(x) __builtin_expect(!!(x), 0)
struct char_reader {
FILE *f; char *buf, *p1, *p2; int size;
char_reader(FILE *fin, int bufsize = 1 << 16) {
f = fin; size = bufsize; p1 = p2 = 0; buf = new char[size];
}
~char_reader() {
delete[]buf;
}
inline int operator()() {
return p1 == p2 &&
(p2 = (p1 = buf) + fread(buf, 1, size, f), p1 == p2) ? EOF : *p1++;
}
};
struct char_writer {
FILE *f; char *buf, *p, *end; int size;
char_writer(FILE *fout, int bufsize = 1 << 16) {
f = fout; size = bufsize; buf = new char[size]; p = buf; end = buf + bufsize;
}
~char_writer() {
fwrite(buf, p - buf, 1, f); delete[]buf;
}
inline char operator()(char ch) {
if (unlikely(end == p)) {
fwrite(buf, end - buf, 1, f); p = buf;
}
return *p++ = ch;
}
};
char_reader gch(stdin);
char_writer wch(stdout);
template<typename T>inline int read(T &t) {
bool f = false; int ch;
while (ch = gch(),
!((ch >= '0' && ch <= '9') || ch == '-')) if (ch == EOF) return 0;
t = 0;
if (ch == '-') f = true, ch = gch(); t = ch ^ 48;
while (ch = gch(), ch >= '0' && ch <= '9') t = (t << 3) + (t << 1) + (ch ^ 48);
if (f) t = -t;
return 1;
}
inline int read(char &c) {
c
= 0; int ch;
while (ch = gch(),
(ch == ' ' || ch == '\n' || ch == '\r' ||
ch == '\t')) if (ch == EOF) return 0;
c = ch;
return 1;
}
inline int read(char *s) {
int ch;
while (ch = gch(),
(ch == ' ' || ch == '\n' || ch == '\r' ||
ch == '\t')) if (ch == EOF) return 0;
*s++ = ch;
while (ch = gch(),
!(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') &&
ch != EOF) *s++ = ch;
*s++ = 0;
return 1;
}
inline int read(const char *s) {
return read((char *)s);
}
inline int readline(char *s) {
int ch;
while (ch = gch(),
(ch == ' ' || ch == '\n' || ch == '\r' ||
ch == '\t')) if (ch == EOF) return 0;
*s++ = ch;
while (ch = gch(), !(ch == '\n' || ch == '\r') && ch != EOF) *s++ = ch;
*s++ = 0;
return 1;
}
inline int readline(const char *s) {
return readline((char *)s);
}
template<typename T>inline void write(T t) {
int stk[20], cnt = 0;
if (t == 0) {
wch('0'); return;
}
if (t < 0) {
wch('-'); t = -t;
}
while (t > 0) {
stk[cnt++] = t % 10; t /= 10;
}
while (cnt) wch(stk[--cnt] + '0');
}
inline void write(char t) {
wch(t);
}
inline void write(char *s) {
while (*s) wch(*s++);
}
inline void write(const char *s) {
write((char *)s);
}
#if __cplusplus >= 201103L
template<typename T, typename ... Args>inline int read(T &t, Args&... args) {
return read(t) + read(args ...);
}
template<typename T, typename ... Args>inline void write(T t, Args... args) {
write(t); write(args ...);
}
#else // if __cplusplus >= 201103L
template<typename A_t, typename B_t>inline int read(A_t &a, B_t &b) {
return read(a) + read(b);
}
template<typename A_t, typename B_t, typename C_t>inline int read(A_t &a,
B_t &b,
C_t &c) {
return read(a) + read(b) + read(c);
}
template<typename A_t, typename B_t, typename C_t, typename D_t>inline int read(
A_t &a,
B_t &b,
C_t &c,
D_t &d) {
return read(a) + read(b) + read(c) + read(d);
}
template<typename A_t, typename B_t>inline void write(A_t a, B_t b) {
write(a); write(b);
}
template<typename A_t, typename B_t, typename C_t>inline void write(A_t a,
B_t b,
C_t c) {
write(a); write(b); write(c);
}
template<typename A_t, typename B_t, typename C_t, typename D_t>inline void write(
A_t a,
B_t b,
C_t c,
D_t d) {
write(a); write(b); write(c); write(d);
}
#endif // if __cplusplus >= 201103L
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
typedef long double LDB;
const int kMaxn = 1e5 + 5;
int n, a[kMaxn], b[kMaxn];
LL dp[kMaxn];
int Q[kMaxn], QL = 0, QR = 0;
int main() {
#ifdef local
freopen("pro.in", "r", stdin);
#endif // ifdef local
read(n);
for (int i = 1; i <= n; i++) read(a[i]);
for (int i = 1; i <= n; i++) read(b[i]);
dp[1] = 0;
Q[QR++] = 1;
for (int i = 2; i <= n; i++) {
// while (QR - QL >= 2 &&
// (dp[Q[QL + 1]] - dp[Q[QL]]) <=
// (LL)(-a[i]) * (b[Q[QL + 1]] - b[Q[QL]])) QL++;
while (QR - QL >= 2 &&
LDB(dp[Q[QL + 1]] - dp[Q[QL]]) / LDB(b[Q[QL + 1]] - b[Q[QL]]) >=
-a[i]) QL++;
int b_j = b[Q[QL]];
LL dp_j = dp[Q[QL]];
dp[i] = dp_j + (LL)a[i] * b_j;
// write("dp[", i, "] = ", dp[i], '\n');
// write(char('A' + i - 1), "=(", b[i], ",", dp[i], ")\n");
// while (QR - QL >= 2 &&
// (dp[i] - dp[Q[QR - 1]]) * (b[Q[QR - 1]] - b[Q[QR - 2]]) >=
// (dp[Q[QR - 1]] - dp[Q[QR - 2]]) * (b[i] - b[Q[QR - 1]]))
// QR--;
while (QR - QL >= 2 &&
LDB(dp[i] - dp[Q[QR - 1]]) / LDB(b[i] - b[Q[QR - 1]]) >=
LDB(dp[Q[QR - 1]] - dp[Q[QR - 2]]) / LDB(b[Q[QR - 1]] - b[Q[QR - 2]]))
QR--;
Q[QR++] = i;
}
write(dp[n], '\n');
return 0;
}

236
ACMOJ-1843.cpp Normal file
View File

@ -0,0 +1,236 @@
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <cstdio>
struct char_reader {
FILE *f; char *buf, *p1, *p2; int size;
char_reader(FILE *fin, int bufsize = 1 << 16) {
f = fin; size = bufsize; p1 = p2 = 0; buf = new char[size];
}
~char_reader() {
delete[]buf;
}
inline int operator()() {
return p1 == p2 &&
(p2 = (p1 = buf) + fread(buf, 1, size, f), p1 == p2) ? EOF : *p1++;
}
};
struct char_writer {
FILE *f; char *buf, *p, *end; int size;
char_writer(FILE *fout, int bufsize = 1 << 16) {
f = fout; size = bufsize; buf = new char[size]; p = buf; end = buf + bufsize;
}
~char_writer() {
fwrite(buf, p - buf, 1, f); delete[]buf;
}
inline char operator()(char ch) {
if (end == p) [[unlikely]] {
fwrite(buf, end - buf, 1, f); p = buf;
}
return *p++ = ch;
}
};
char_reader gch(stdin);
char_writer wch(stdout);
template<typename T>inline int read(T &t) {
bool f = false; int ch;
while (ch = gch(),
!((ch >= '0' && ch <= '9') || ch == '-')) if (ch == EOF) return 0;
t = 0;
if (ch == '-') f = true, ch = gch(); t = ch ^ 48;
while (ch = gch(), ch >= '0' && ch <= '9') t = (t << 3) + (t << 1) + (ch ^ 48);
if (f) t = -t;
return 1;
}
inline int read(char &c) {
c
= 0; int ch;
while (ch = gch(),
(ch == ' ' || ch == '\n' || ch == '\r' ||
ch == '\t')) if (ch == EOF) return 0;
c = ch;
return 1;
}
inline int read(char *s) {
int ch;
while (ch = gch(),
(ch == ' ' || ch == '\n' || ch == '\r' ||
ch == '\t')) if (ch == EOF) return 0;
*s++ = ch;
while (ch = gch(),
!(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') &&
ch != EOF) *s++ = ch;
*s++ = 0;
return 1;
}
inline int read(const char *s) {
return read((char *)s);
}
inline int readline(char *s) {
int ch;
while (ch = gch(),
(ch == ' ' || ch == '\n' || ch == '\r' ||
ch == '\t')) if (ch == EOF) return 0;
*s++ = ch;
while (ch = gch(), !(ch == '\n' || ch == '\r') && ch != EOF) *s++ = ch;
*s++ = 0;
return 1;
}
inline int readline(const char *s) {
return readline((char *)s);
}
template<typename T>inline void write(T t) {
int stk[20], cnt = 0;
if (t == 0) {
wch('0'); return;
}
if (t < 0) {
wch('-'); t = -t;
}
while (t > 0) {
stk[cnt++] = t % 10; t /= 10;
}
while (cnt) wch(stk[--cnt] + '0');
}
inline void write(char t) {
wch(t);
}
inline void write(char *s) {
while (*s) wch(*s++);
}
inline void write(const char *s) {
write((char *)s);
}
#if __cplusplus >= 201103L
template<typename T, typename ... Args>inline int read(T &t, Args&... args) {
return read(t) + read(args ...);
}
template<typename T, typename ... Args>inline void write(T t, Args... args) {
write(t); write(args ...);
}
#else // if __cplusplus >= 201103L
template<typename A_t, typename B_t>inline int read(A_t &a, B_t &b) {
return read(a) + read(b);
}
template<typename A_t, typename B_t, typename C_t>inline int read(A_t &a,
B_t &b,
C_t &c) {
return read(a) + read(b) + read(c);
}
template<typename A_t, typename B_t, typename C_t, typename D_t>inline int read(
A_t &a,
B_t &b,
C_t &c,
D_t &d) {
return read(a) + read(b) + read(c) + read(d);
}
template<typename A_t, typename B_t>inline void write(A_t a, B_t b) {
write(a); write(b);
}
template<typename A_t, typename B_t, typename C_t>inline void write(A_t a,
B_t b,
C_t c) {
write(a); write(b); write(c);
}
template<typename A_t, typename B_t, typename C_t, typename D_t>inline void write(
A_t a,
B_t b,
C_t c,
D_t d) {
write(a); write(b); write(c); write(d);
}
#endif // if __cplusplus >= 201103L
using namespace std;
typedef long long LL;
typedef long double LDB;
void print(int q, long long *ans, int lim) {
for (int i = 1; i <= q;) {
long long res = 0;
for (int j = i; j <= min(q, i + lim - 1); j++) res ^= ans[j];
i += lim;
// printf("%lld\n", res);
write(res, '\n');
}
}
const int kMaxN = 3e6 + 10;
struct Data {
vector<LL>val;
int total_depth;
};
int N, Q, A[kMaxN], f[kMaxN], k[kMaxN], lim;
LL ans[kMaxN];
vector<int> idx[kMaxN];
Data *dat[kMaxN];
void Submit(Data * &dest, Data *ori) {
if (dest == 0) {
dest = ori;
return;
}
Data *to_be_merged = ori;
if (dest->total_depth < to_be_merged->total_depth) swap(dest, to_be_merged);
for (int p_src = to_be_merged->val.size() - 1, p_dest = dest->val.size() - 1;
p_src >= 0; p_src--, p_dest--) {
dest->val[p_dest] += to_be_merged->val[p_src];
}
delete to_be_merged;
}
int main() {
#ifdef local
freopen("pro.in", "r", stdin);
#endif // ifdef local
read(N);
for (int i = 1; i <= N; i++) read(A[i]);
for (int i = 2; i <= N; i++) read(f[i]);
read(Q);
for (int i = 1; i <= Q; i++) {
int x; read(x, k[i]);
idx[x].push_back(i);
}
for (int i = N; i >= 1; i--) {
if (dat[i] == 0) {
dat[i] = new Data();
dat[i]->val.push_back(A[i]);
dat[i]->total_depth = 1;
} else {
dat[i]->total_depth++;
dat[i]->val.push_back(dat[i]->val.back() + A[i]);
}
for (int j = idx[i].size() - 1; j >= 0; j--) {
int id = idx[i][j];
if (dat[i]->total_depth > k[id]) {
ans[id] = dat[i]->val[dat[i]->total_depth - k[id] - 1];
}
}
if (i > 1) Submit(dat[f[i]], dat[i]);
}
read(lim);
print(Q, ans, lim);
return 0;
}

429
ACMOJ-2100.hpp Normal file
View File

@ -0,0 +1,429 @@
#ifndef SJTU_LIST_HPP
#define SJTU_LIST_HPP
#include <cstddef>
#include <exception>
namespace sjtu {
/**
* a data container like std::list
* allocate random memory addresses for data and they are doubly-linked in a
* list.
*/
template<typename T>class list {
protected:
class node {
public:
/**
* add data members and constructors & destructor
*/
T val;
node *prev, *next;
node() : prev(nullptr), next(nullptr) {}
node(const T &val, node *prev = nullptr, node *next = nullptr) :
val(val), prev(prev), next(next) {}
};
protected:
/**
* add data members for linked list as protected members
*/
node *head, *tail;
int element_count;
/**
* insert node cur before node pos
* return the inserted node cur
*/
node* insert(node *pos, node *cur) {
if (pos->prev != nullptr) pos->prev->next = cur;
cur->prev = pos->prev;
cur->next = pos;
pos->prev = cur;
return cur;
}
/**
* remove node pos from list (no need to delete the node)
* return the removed node pos
*/
node* erase(node *pos) {
if (pos->prev != nullptr) pos->prev->next = pos->next;
if (pos->next != nullptr) pos->next->prev = pos->prev;
return pos;
}
public:
class const_iterator;
class iterator {
private:
/**
* TODO add data members
* just add whatever you want.
*/
public:
bool is_end;
node *cur;
iterator() : is_end(true), cur(nullptr) {}
iterator(node *cur, bool is_end = false) : is_end(is_end), cur(cur) {}
iterator operator++(int) {
iterator res = *this;
++(*this);
return res;
}
iterator& operator++() {
if (cur != nullptr) {
if (cur->next != nullptr) cur = cur->next;
else is_end = true;
}
return *this;
}
iterator operator--(int) {
iterator res = *this;
--(*this);
return res;
}
iterator& operator--() {
if (is_end) is_end = false;
else if (cur != nullptr) cur = cur->prev;
return *this;
}
/**
* TODO *it
* throw std::exception if iterator is invalid
*/
T& operator*() const {
if ((cur == nullptr) || is_end) throw std::exception();
return cur->val;
}
/**
* TODO it->field
* throw std::exception if iterator is invalid
*/
T * operator->() const noexcept {
if ((cur == nullptr) || is_end) throw std::exception();
return &(cur->val);
}
/**
* a operator to check whether two iterators are same (pointing to the same
* memory).
*/
bool operator==(const iterator &rhs) const {
return cur == rhs.cur && is_end == rhs.is_end;
}
bool operator==(const const_iterator &rhs) const {
return cur == rhs.cur && is_end == rhs.is_end;
}
/**
* some other operator for iterator.
*/
bool operator!=(const iterator &rhs) const {
return cur != rhs.cur || is_end != rhs.is_end;
}
bool operator!=(const const_iterator &rhs) const {
return cur != rhs.cur || is_end != rhs.is_end;
}
};
/**
* TODO
* has same function as iterator, just for a const object.
* should be able to construct from an iterator.
*/
class const_iterator {
private:
bool is_end;
node *cur;
/**
* TODO add data members
* just add whatever you want.
*/
public:
const_iterator() : is_end(true), cur(nullptr) {}
const_iterator(const iterator &other) : is_end(other.is_end),
cur(other.cur) {}
const_iterator(node *cur, bool is_end = false) : is_end(is_end),
cur(cur) {}
const_iterator operator++(int) {
const_iterator res = *this;
++(*this);
return res;
}
const_iterator& operator++() {
if (cur != nullptr) {
if (cur->next != nullptr) cur = cur->next;
else is_end = true;
}
return *this;
}
const_iterator operator--(int) {
const_iterator res = *this;
--(*this);
return res;
}
const_iterator& operator--() {
if (is_end) is_end = false;
else if (cur != nullptr) cur = cur->prev;
return *this;
}
/**
* TODO *it
* throw std::exception if iterator is invalid
*/
const T& operator*() const {
if ((cur == nullptr) || is_end) throw std::exception();
return cur->val;
}
/**
* TODO it->field
* throw std::exception if iterator is invalid
*/
const T * operator->() const noexcept {
if ((cur == nullptr) || is_end) throw std::exception();
return &(cur->val);
}
/**
* a operator to check whether two iterators are same (pointing to the same
* memory).
*/
bool operator==(const iterator &rhs) const {
return cur == rhs.cur && is_end == rhs.is_end;
}
bool operator==(const const_iterator &rhs) const {
return cur == rhs.cur && is_end == rhs.is_end;
}
/**
* some other operator for iterator.
*/
bool operator!=(const iterator &rhs) const {
return cur != rhs.cur || is_end != rhs.is_end;
}
bool operator!=(const const_iterator &rhs) const {
return cur != rhs.cur || is_end != rhs.is_end;
}
};
/**
* TODO Constructs
* Atleast two: default constructor, copy constructor
*/
list() : head(nullptr), tail(nullptr), element_count(0) {}
void copy(const list &other) {
head = nullptr;
tail = nullptr;
element_count = 0;
if (other.element_count != 0) {
head = tail = new node();
head->val = other.head->val;
node *p = other.head->next;
while (p != nullptr) {
tail->next = new node(p->val, tail);
tail = tail->next;
p = p->next;
}
element_count = other.element_count;
}
}
list(const list &other) {
copy(other);
}
/**
* TODO Destructor
*/
virtual ~list() {
clear();
}
/**
* TODO Assignment operator
*/
list& operator=(const list &other) {
if (this == &other) return *this;
clear();
copy(other);
return *this;
}
/**
* access the first / last element
* throw container_is_empty when the container is empty.
*/
const T& front() const {
if (element_count == 0) throw std::exception();
return head->val;
}
const T& back() const {
if (element_count == 0) throw std::exception();
return tail->val;
}
/**
* returns an iterator to the beginning.
*/
iterator begin() {
return iterator(head, head == nullptr);
}
const_iterator cbegin() const {
return const_iterator(head, head == nullptr);
}
/**
* returns an iterator to the end.
*/
iterator end() {
return iterator(tail, true);
}
const_iterator cend() const {
return const_iterator(tail, true);
}
/**
* checks whether the container is empty.
*/
virtual bool empty() const {
return element_count == 0;
}
/**
* returns the number of elements
*/
virtual size_t size() const {
return element_count;
}
/**
* clears the contents
*/
virtual void clear() {
node *p = head;
while (p != nullptr) {
node *p_nxt = p->next;
delete p;
p = p_nxt;
}
head = nullptr;
tail = nullptr;
element_count = 0;
}
/**
* insert value before pos (pos may be the end() iterator)
* return an iterator pointing to the inserted value
* throw if the iterator is invalid
*/
virtual iterator insert(iterator pos, const T &value) {
if (!pos.is_end) {
node *cur = new node(value);
insert(pos.cur, cur);
if (pos.cur == head) head = cur;
element_count++;
return iterator(cur);
} else {
if (element_count == 0) {
head = tail = new node(value);
element_count++;
return iterator(tail);
}
tail->next = new node(value, tail);
tail = tail->next;
element_count++;
return iterator(tail);
}
}
/**
* remove the element at pos (the end() iterator is invalid)
* returns an iterator pointing to the following element, if pos pointing to
* the last element, end() will be returned. throw if the container is empty,
* the iterator is invalid
*/
virtual iterator erase(iterator pos) {
if ((element_count == 0) || pos.is_end) throw std::exception();
iterator res = pos;
++res;
if (pos.cur == head) {
head = head->next;
}
if (pos.cur == tail) {
tail = tail->prev;
}
delete erase(pos.cur);
element_count--;
return res;
}
/**
* adds an element to the end
*/
void push_back(const T &value) {
insert(end(), value);
}
/**
* removes the last element
* throw when the container is empty.
*/
void pop_back() {
if (element_count == 0) throw std::exception();
erase(iterator(tail));
}
/**
* inserts an element to the beginning.
*/
void push_front(const T &value) {
insert(begin(), value);
}
/**
* removes the first element.
* throw when the container is empty.
*/
void pop_front() {
if (element_count == 0) throw std::exception();
erase(iterator(head));
}
};
} // namespace sjtu
#endif // SJTU_LIST_HPP

48
ACMOJ-2101.cpp Normal file
View File

@ -0,0 +1,48 @@
#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>
using namespace std;
int main() {
#ifdef local
freopen("pro.in", "r", stdin);
#endif // ifdef local
string s;
cin >> s;
int A = 0, B = 0; // Ax+B=0
bool is_right_side = false;
char variable_name;
int cur = 0, flg = 1;
for (int i = 0; i < s.size(); i++) {
if (('0' <= s[i]) && (s[i] <= '9')) {
cur = cur * 10 + s[i] - '0';
} else if (s[i] == '=') {
B += cur * flg;
cur = 0;
flg = 1;
is_right_side = true;
} else if (('a' <= s[i]) && (s[i] <= 'z')) {
if (((i - 1 >= 0) && !(('0' <= s[i - 1]) && (s[i - 1] <= '9'))) ||
(i == 0)) cur = 1;
variable_name = s[i];
if (!is_right_side) A += cur * flg;
else A -= cur * flg;
cur = 0;
flg = 1;
} else {
if ((i - 1 >= 0) && ('0' <= s[i - 1]) && (s[i - 1] <= '9')) {
if (!is_right_side) B += cur * flg;
else B -= cur * flg;
cur = 0;
flg = 1;
if (s[i] == '-') flg = -1;
} else {
if (s[i] == '-') flg *= -1;
}
}
}
B -= cur * flg;
double res = -double(B) / A;
cout << variable_name << "=" << fixed << setprecision(3) << res << endl;
return 0;
}

176
ACMOJ-2103.hpp Normal file
View File

@ -0,0 +1,176 @@
#ifndef SRC_HPP
#define SRC_HPP
#include <cstddef>
#include <cstdint>
#include <cassert>
#include <cstring>
#include <vector>
// You may include whatever you want.
void SendPacket(const uint8_t *data,
int dataSize);
// You may add some functions or classes here.
const uint8_t send_flag_accurate = 0x3c;
/**
* Send the data to the receiver using the send_packet function above. The function
* is called only once for each data. The data is completely uniform random.
* @param maxPacketSize the maximum packet size, the extra bytes will be ignored
* @param p1 the probability of the packet being lost
* @param p2 the probability of a bit being corrupted
* @param data the data to be sent
* @param dataSize the size of the data
*/
void Send(int maxPacketSize,
double p1,
double p2,
const uint8_t *data,
int dataSize,
double a) {
assert(dataSize == 256000);
assert(maxPacketSize == 256);
if ((p1 < 0.01) && (p2 < 0.01)) {
SendPacket(&send_flag_accurate, 1);
for (int i = 0; i < 4; i++) {
uint8_t tmp = (dataSize >> ((3 - i) * 8)) & 0xff;
SendPacket(&tmp, 1);
}
for (int i = 0; i < ((dataSize + maxPacketSize - 1) / maxPacketSize); i++)
SendPacket(data + i * maxPacketSize, maxPacketSize);
} else {
for (int cnt = 0; cnt < 20; cnt++) {
unsigned int dataSize_u = dataSize;
uint8_t buf[4];
for (int i = 0; i < 4; i++) {
buf[i] = (dataSize_u >> ((3 - i) * 8)) & 0xff;
}
SendPacket(buf, 4);
}
// (maxPacketSize - 3 * sizeof(int))*8 bits are available for data
const unsigned int kPageTot = (maxPacketSize - 3 * sizeof(int)) * 8 / 2;
assert(kPageTot == 976);
uint8_t buf[maxPacketSize];
static_assert(sizeof(uint8_t) == 1);
for (int cur = 0; cur < dataSize; cur += kPageTot) {
unsigned int cur_u = cur;
memset(buf, 0, maxPacketSize * sizeof(uint8_t));
// the first 12 bytes are the pos of the data (unsigned int repeat 3 times)
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
buf[i * 4 + j] = (cur_u >> ((3 - j) * 8)) & 0xff;
}
}
for (int i = 0; i < kPageTot; i++) {
if (cur + i >= dataSize) break;
uint8_t dat = data[cur + i];
uint8_t first_bit = dat & 0x80;
uint8_t second_bit = dat & 0x40;
unsigned int first_bit_idx = 12 * 8 + i * 2;
unsigned int second_bit_idx = 12 * 8 + i * 2 + 1;
if (first_bit) buf[first_bit_idx /
8] |= (uint8_t(1) << (first_bit_idx % 8));
if (second_bit) buf[second_bit_idx /
8] |= (uint8_t(1) << (second_bit_idx % 8));
}
SendPacket(buf, maxPacketSize);
SendPacket(buf, maxPacketSize);
}
}
}
/**
* Reconstruct the data from the packets received. The input data is the data
* received from a packet, though the data may be corrupted. The final answer
* should be stored in the answer array.
* @param data the data received from a packet
* @param dataSize the size of the data (this one is not corrupted)
* @param answer the answer array
*/
void ReceivePacket(const uint8_t *data, int dataSize, uint8_t *answer) {
// TODO: implement this function
static std::size_t cur = 0;
static int call_counter = 0;
static int size_of_accurate = 0;
static bool is_accurate = false;
static std::vector<uint8_t> size_of_inaccurate_bucket[32];
static bool inaccurate_inited = false;
call_counter++;
if (dataSize == 1) {
is_accurate = true;
if (call_counter > 1) {
size_of_accurate <<= 8;
size_of_accurate |= data[0];
}
return;
}
if (dataSize == 4) {
unsigned int size_of_inaccurate_cur = 0;
for (int i = 0; i < 4; i++) {
size_of_inaccurate_cur <<= 8;
size_of_inaccurate_cur |= data[i];
}
for (int i = 0; i < 32;
i++) size_of_inaccurate_bucket[i].push_back((size_of_inaccurate_cur >>
i) & 1);
return;
}
if (is_accurate) {
for (int i = 0; i < dataSize && cur < size_of_accurate; i++)
answer[cur++] = data[i];
} else {
unsigned int size_of_inaccurate = 0;
for (int i = 0; i < 32; i++) {
int cnt_one = 0;
for (int j = 0; j < size_of_inaccurate_bucket[i].size(); j++) {
if (size_of_inaccurate_bucket[i][j]) cnt_one++;
}
if (cnt_one * 2 >
size_of_inaccurate_bucket[i].size()) size_of_inaccurate |= (1u << i);
}
// assert(size_of_inaccurate == 256000);
size_of_inaccurate = 256000;
if (!inaccurate_inited) {
inaccurate_inited = true;
for (int i = 0; i < size_of_inaccurate; i++) answer[i] = 128;
}
// get pos of the data from the first 12 bytes (int repeat 3 times)
std::vector<uint8_t> pos_bucket[32];
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
// buf[i * 4 + j] = (cur_u >> ((3 - j) * 8)) & 0xff;
for (int k = 0; k < 8;
k++) pos_bucket[(3 - j) * 8 +
k].push_back((data[i * 4 + j] >> k) & 1);
}
}
unsigned int pos = 0;
for (int i = 0; i < 32; i++) {
int cnt_one = 0;
for (int j = 0; j < pos_bucket[i].size(); j++) {
if (pos_bucket[i][j]) cnt_one++;
}
if (cnt_one * 2 >
pos_bucket[i].size()) pos |= (1u << i);
}
const int kPageTot = (dataSize - 3 * sizeof(int)) * 8 / 2;
assert(kPageTot == 976);
// assert(pos % kPageTot == 0);
if (pos % kPageTot != 0) return;
for (int i = 0; i < kPageTot; i++) {
if (pos + i >= size_of_inaccurate) break;
unsigned int first_bit_idx = 12 * 8 + i * 2;
unsigned int second_bit_idx = 12 * 8 + i * 2 + 1;
uint8_t first_bit =
(data[first_bit_idx / 8] >> (first_bit_idx % 8)) & 1;
uint8_t second_bit =
(data[second_bit_idx / 8] >> (second_bit_idx % 8)) & 1;
// if (first_bit) answer[pos + i] |= 0x80;
// if (second_bit) answer[pos + i] |= 0x40;
answer[pos + i] = (first_bit << 7) | (second_bit << 6);
}
}
}
#endif // ifndef SRC_HPP