Skip to content

Commit

Permalink
4.10b
Browse files Browse the repository at this point in the history
  • Loading branch information
dtcxzyw committed Apr 10, 2019
1 parent 77b6845 commit e6a1c8c
Show file tree
Hide file tree
Showing 17 changed files with 241 additions and 32 deletions.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ SpacesInParentheses: false
# 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响
SpacesInSquareBrackets: false
# 标准: Cpp03, Cpp11, Auto
Standard: Cpp03
Standard: Cpp11
# tab宽度
TabWidth: 4
# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
Expand Down
9 changes: 5 additions & 4 deletions Checker/Adapters/BZOJJudger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ static bool readOpt(Option& opt,
const std::string& str) {
std::string title;
{
std::regex pattern("<title>(\\S+)</title>",
regexFlag4Search);
std::regex pattern(
"<title>\\s*([ \\S]+)\\s*</title>",
regexFlag4Search);
std::smatch match;
std::regex_search(str, match, pattern);
if(match.size() == 2)
Expand All @@ -20,7 +21,7 @@ static bool readOpt(Option& opt,
int64_t maxTime = 0;
{
std::regex pattern(
"[:|</span>]([0-9]+)[s|Sec]",
"[:|</span>]([0-9]+)[s| ?Sec]",
regexFlag4Search);
std::smatch match;
std::regex_search(str, match, pattern);
Expand All @@ -31,7 +32,7 @@ static bool readOpt(Option& opt,
}
int64_t maxMem = 0;
{
std::regex pattern("([0-9]+)MB",
std::regex pattern("([0-9]+) ?MB",
regexFlag4Search);
std::smatch match;
std::regex_search(str, match, pattern);
Expand Down
10 changes: 5 additions & 5 deletions Checker/Adapters/LOJJudger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ static bool readOpt(Option& opt,
const std::string& str) {
std::string title;
{
std::regex pattern(
"<h1class=\"uiheader\">(\\S+)</h1>",
regexFlag4Search);
std::regex pattern("<h1class=\"uiheader\">\\s*"
"([ \\S]+)\\s*</h1>",
regexFlag4Search);
std::smatch match;
std::regex_search(str, match, pattern);
if(match.size() == 2)
Expand All @@ -22,7 +22,7 @@ static bool readOpt(Option& opt,
}
int64_t maxTime = 0;
{
std::regex pattern("([0-9]+)ms</span>",
std::regex pattern("([0-9]+) ms</span>",
regexFlag4Search);
std::smatch match;
std::regex_search(str, match, pattern);
Expand All @@ -33,7 +33,7 @@ static bool readOpt(Option& opt,
}
int64_t maxMem = 0;
{
std::regex pattern("([0-9]+)MiB</span>",
std::regex pattern("([0-9]+) MiB</span>",
regexFlag4Search);
std::smatch match;
std::regex_search(str, match, pattern);
Expand Down
2 changes: 1 addition & 1 deletion Checker/Checker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ int main() {
std::cout.precision(2);
std::cout << std::fixed;

line("Checker 2.8.0", '*');
line("Checker 2.8.1", '*');
std::cout << "Built at " << __TIME__ << " on "
<< __DATE__ << std::endl;
platformInfo();
Expand Down
26 changes: 16 additions & 10 deletions Checker/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <fstream>
#include <iostream>
#include <iterator>
#include <random>
#ifdef __WIN32
#include <windows.h>
#else
Expand All @@ -16,8 +17,12 @@
#include <vector>
std::string file2Str(const fs::path& path) {
std::ifstream in(path);
using Iter = std::istream_iterator<char>;
return { Iter(in), Iter() };
in.seekg(0, std::ios::end);
auto siz = in.tellg();
in.seekg(0, std::ios::beg);
std::vector<char> data(siz);
in.read(data.data(), siz);
return std::string(data.data(), data.data() + siz);
}
static int getConsoleWidth() {
#ifdef __WIN32
Expand Down Expand Up @@ -56,21 +61,22 @@ bool Data::operator<(const Data& rhs) const {
return input < rhs.input;
}
static fs::path uniqueTempFileName() {
std::string temp =
(fs::temp_directory_path() / "TMP_XXXXXX")
.string();
if(mkstemp(temp.data()) == -1)
throw std::runtime_error(
"Failed to create temp file.");
return temp;
static std::mt19937_64 dev(
std::chrono::high_resolution_clock::now()
.time_since_epoch()
.count());
return fs::temp_directory_path() /
std::to_string(dev());
}
TempFile::TempFile() : mFile(uniqueTempFileName()) {}
fs::path TempFile::path() const {
return mFile;
}
TempFile::~TempFile() {
if(fs::exists(mFile))
try {
fs::remove(mFile);
} catch(...) {
}
}
static void clearCache() {
if(fs::exists("Cache")) {
Expand Down
10 changes: 7 additions & 3 deletions Checker/Platforms/PlatformWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ Win32APIError::Win32APIError(const SourceLocation& loc)
const char* Win32APIError::name() const noexcept {
return "Win32API";
}
std::string
Win32APIError::message(int cond) const noexcept {
std::string Win32APIError::message(int cond) const
noexcept {
return "\033[35mSystem Error:\nError Code: " +
std::to_string(cond) + "\nError Message: " +
winerr2String(cond) + "\nFunction: " +
Expand Down Expand Up @@ -43,6 +43,10 @@ void winAssert(WINBOOL res,
if(res == FALSE)
reportError(loc);
}
void setCodePage(int codePage) {
winAssert(SetConsoleCP(codePage));
winAssert(SetConsoleOutputCP(codePage));
}
void initPlatform() {
HANDLE ohnd = GetStdHandle(STD_OUTPUT_HANDLE);
if(ohnd == INVALID_HANDLE_VALUE)
Expand All @@ -52,7 +56,7 @@ void initPlatform() {
winAssert(SetConsoleMode(
ohnd,
old | ENABLE_VIRTUAL_TERMINAL_PROCESSING));
winAssert(SetConsoleCP(65001));
setCodePage(65001);
}
void platformInfo() {
system("ver");
Expand Down
5 changes: 3 additions & 2 deletions Checker/Platforms/PlatformWindows.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ class Win32APIError final
public:
Win32APIError(const SourceLocation& loc);
const char* name() const noexcept override;
std::string
message(int cond) const noexcept override;
std::string message(int cond) const
noexcept override;
~Win32APIError() override = default;
};
[[noreturn]] void
Expand All @@ -31,3 +31,4 @@ class Handle final : private Unmovable {
void winAssert(WINBOOL res,
const SourceLocation& loc =
SourceLocation::current());
void setCodePage(int codePage);
4 changes: 3 additions & 1 deletion Checker/RunnerWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static RunResult runImpl(const Option& opt,
NULL);
Handle ohnd = CreateFileW(
out.c_str(), GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, NULL);
std::pair<HANDLE, HANDLE> phnd =
launch(opt, ihnd, ohnd);
Handle process(phnd.first);
Expand Down Expand Up @@ -131,7 +131,9 @@ RunResult run(const Option& opt, const Timer& timer,
try {
return runImpl(opt, timer, in, out);
} catch(const std::system_error& err) {
setCodePage(936);
std::cout << err.what() << std::endl;
setCodePage(65001);
RunResult res;
res.st = Status::SE;
return res;
Expand Down
2 changes: 1 addition & 1 deletion Checker/build.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ g++ Common.cpp Judger.cpp OJAdapter.cpp OJAPI.cpp Timer.cpp ^
PerfAnalyzer.cpp RunnerShared.cpp Scanner.cpp Checker.cpp ^
RunnerWindows.cpp Platforms/PlatformWindows.cpp Adapters/BZOJJudger.cpp ^
Adapters/LOJJudger.cpp Adapters/DefaultJudger.cpp ^
-o ../bin/checker.out -O2 -std=c++17 -lstdc++fs -Wall -Wextra -v -D__WIN32
-o ../bin/checker.out -O2 -std=c++17 -lstdc++fs -Wall -Wextra -D__WIN32 -DUNICODE -D_UNICODE
2 changes: 1 addition & 1 deletion Checker/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ g++ Common.cpp Judger.cpp OJAdapter.cpp OJAPI.cpp Timer.cpp \
PerfAnalyzer.cpp RunnerShared.cpp Scanner.cpp Checker.cpp RunnerLinux.cpp \
Adapters/BZOJJudger.cpp Adapters/LOJJudger.cpp Adapters/DefaultJudger.cpp \
Platforms/PlatformLinux.cpp \
-o ../bin/checker.out -O2 -std=c++17 -lstdc++fs -Wall -Wextra -time
-o ../bin/checker.out -O2 -std=c++17 -lstdc++fs -Wall -Wextra
3 changes: 3 additions & 0 deletions Checker/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ AC后询问OJ上的时间并加入samples中,在BZOJ计时方式下skip掉剩
2.8.0(4.9)
初步跨Windows平台,并且将评测有关文件移至临时文件夹

2.8.1(4.10)
解决Windows平台下控制台输出乱码问题

## TODO List

- [x] 跨Windows平台、分离平台实现
Expand Down
4 changes: 2 additions & 2 deletions Queue.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,8 +435,8 @@
- [ ] bzoj3501
- [ ] bzoj1902
- [ ] bzoj2111
- [ ] bzoj4454
- [ ] BZOJ3884
- [x] bzoj4454
- [x] BZOJ3884
# 线段树相关
- [x] LOJ#2013. 「SCOI2016」幸运数字
- [x] LOJ#6057. 「HNOI2016」序列 数据加强版
Expand Down
31 changes: 31 additions & 0 deletions Review/NumberTheory/GCD.tex
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,34 @@ \subsubsection{实现}
return a|b;
}
\end{lstlisting}
\subsection{O(n)-O(1)gcd}
例题:BZOJ4454 C Language Practice

该算法依赖于这个定理:
\begin{theorem}
任意正整数$x$都可以分解为$x_1x_2x_3$的形式,其中$x_i$要么$\leq\sqrt{x}$,要么是素数。
\end{theorem}

在计算$gcd(x,y)$时,如果我们知道了$x$的分解$x_1x_2x_3$,那么答案可以表示为
$gcd(x_1,y)gcd(x_2,y')gcd(x_3,y'')$,其中$y'$$y$消去因子$gcd(x_1,y)$后的值,$y''$类似。

接下来分类讨论计算(记$n=max\left\{x\right\}$):
\begin{itemize}
\item$x_i\leq \sqrt{n}$,那么可以$O(n)$预处理$1\sim \sqrt{n}$两两之间的gcd
(利用$gcd(x,y)=gcd(x-y,y)$递推),然后$O(1)$查询$gcd(x_i,y\%x_i)$
\item 否则$x_i$是素数,判断$x_i$是否整除$y$
\end{itemize}

至于计算$x$的因式分解,可以使用线性筛筛出最小质因子$d$,然后使用$x/d$的因子分解递推出
$x$的分解,选取最小的因子乘以$d$

参考代码:
\lstinputlisting{Source/Source/'Number Theory'/bzoj4454.cpp}

该方法参考了wzj\footnote{
BZOJ4454: C Language Practice
\url{https://www.cnblogs.com/wzj-is-a-juruo/p/5316963.html}
}和fjzzq2002\footnote{
O(1) 查询gcd
\url{https://www.cnblogs.com/zzqsblog/p/5436775.html}
}的博客。
40 changes: 40 additions & 0 deletions Source/Number Theory/bzoj3884.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <cstdio>
int phi(int n) {
int res = n;
for(int i = 2; i * i <= n; ++i)
if(n % i == 0) {
do
n /= i;
while(n % i == 0);
res = res / i * (i - 1);
}
if(n != 1)
res = res / n * (n - 1);
return res;
}
typedef long long Int64;
Int64 powm(Int64 a, int k, int mod) {
Int64 res = 1;
while(k) {
if(k & 1)
res = res * a % mod;
k >>= 1, a = a * a % mod;
}
return res;
}
int foo(int t) {
if(t == 1)
return 0;
int x = phi(t);
return powm(2, foo(x) + x, t);
}
int main() {
int t;
scanf("%d", &t);
for(int i = 1; i <= t; ++i) {
int x;
scanf("%d", &x);
printf("%d\n", foo(x));
}
return 0;
}
Loading

0 comments on commit e6a1c8c

Please sign in to comment.