Skip to content

Commit

Permalink
3.23
Browse files Browse the repository at this point in the history
  • Loading branch information
dtcxzyw committed Mar 23, 2019
1 parent 915c10b commit bc36dcb
Show file tree
Hide file tree
Showing 13 changed files with 728 additions and 51 deletions.
8 changes: 5 additions & 3 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
"-o",
"bin/${fileBasenameNoExtension}.out",
"-Wall",
"-std=c++11",
"-std=c++17",
"-D_FORTIFY_SOURCE=2",
"-fstack-protector-all",
"-ftrapv",
"-ggdb3",
"-Wextra"
"-Wextra",
"-lstdc++fs"
],
"problemMatcher": {
"owner": "cpp",
Expand All @@ -42,7 +43,8 @@
"-o",
"bin/${fileBasenameNoExtension}.out",
"-Wall",
"-std=c++11"
"-std=c++17",
"-lstdc++fs"
],
"problemMatcher": {
"owner": "cpp",
Expand Down
1 change: 1 addition & 0 deletions Review/Main.tex
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ \chapter{前言}
\include{CG/CG}
\include{Optmize/Optmize}
\include{Theory/Theory}
\include{STL/STL}
\include{Other/Other}
\appendix
\include{Recommendation}
Expand Down
9 changes: 9 additions & 0 deletions Review/Other/TricksAndIdeas.tex
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ \subsubsection{回滚莫队}

\lstinputlisting{Source/Source/Block/LOJ2874.cpp}

对于删除容易插入难的操作也可以这样做。

上述内容参考了yashem66的博客\footnote{
BZOJ4241 历史研究 (分块 回滚莫队-教程向)
\url{https://blog.csdn.net/qq\_33330876/article/details/73522230}
Expand Down Expand Up @@ -459,6 +461,11 @@ \subsection{注意事项/常见转化/思想}
\item 单向限制+强制在线:重构树
\item 双向限制+可离线:扫描线+LCT
\end{itemize}
\item 连通块计数
\begin{itemize}
\item 树上连通块个数=点数-边数
\item 网格图四连通块个数=格子数-1*2矩形数-2*1矩形数+2*2矩形数+环数
\end{itemize}
\end{itemize}
\subsection{比赛注意事项}
\subsubsection{Linux/GCC工具}
Expand Down Expand Up @@ -516,6 +523,8 @@ \subsubsection{代码注意事项}
\item 删除std::multiset内的单个元素时要使用迭代器
\item std::set的插入最好使用hint与区间。
\item (分段)打表时注意源代码不能超过100KB。
\item 不要使用std::bitset的set与test,它们会执行越界检查。不过operator[]的性能
尚未验证,因为它们的返回值是bool的Proxy Class————std::bitset::reference。
\end{itemize}
\subsection{本节注记}
2013年许昊然的国家集训队论文答辩《浅谈数据结构题的几个非经典解法——<Claymore>命题报告》
Expand Down
3 changes: 3 additions & 0 deletions Review/STL/STL.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
\chapter{标准库应用}
\minitoc
\input{STL/bitset}
10 changes: 10 additions & 0 deletions Review/STL/bitset.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
\section{bitset}
{\bfseries Warning:不要使用test和set成员函数,使用operator[]代替。}

\subsection{bitset高精度模板}
二进制加减法均可以省去十进制加减的进借位讨论。并且二进制存储具有更高的数据密度。

{\bfseries Warning:bitset是定长的,大量较小数的运算会造成冗余计算。一般
适用于1024bit以内计算。}

为了支持负数,下面算法均使用补码表示。
7 changes: 7 additions & 0 deletions Review/SetAndGroupTheory/PermutationGroups.tex
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,10 @@ \subsection{完全图染色问题}
\lstinputlisting{Source/Source/Groop/4727.cpp}

上述内容参考了陈瑜希的论文《Pólya计数法的应用》。
\subsection{置换的群性质}
注意单个置换可以生成群,且满足结合律,因此。。。

\begin{itemize}
\item 置换快速幂
\item 置换BSGS求离散对数
\end{itemize}
186 changes: 186 additions & 0 deletions Source/Competition/APIO/LOJ2310.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
int read() {
int res = 0, c;
do
c = getchar();
while(c < '0' || c > '9');
while('0' <= c && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
return res;
}
const int size = 200005;
struct Node {
int l, r, siz;
} T[size * 60];
int tcnt = 0;
int insert(int l, int r, int src, int p) {
int id = ++tcnt;
T[id] = T[src];
++T[id].siz;
if(l != r) {
int m = (l + r) >> 1;
if(p <= m)
T[id].l = insert(l, m, T[id].l, p);
else
T[id].r = insert(m + 1, r, T[id].r, p);
}
return id;
}
int query(int l, int r, int a, int b, int nl, int nr) {
if(T[a].siz == T[b].siz)
return 0;
if(nl <= l && r <= nr)
return T[b].siz - T[a].siz;
int m = (l + r) >> 1, res = 0;
if(nl <= m)
res += query(l, m, T[a].l, T[b].l, nl, nr);
if(m < nr)
res += query(m + 1, r, T[a].r, T[b].r, nl, nr);
return res;
}
typedef long long Int64;
#define asInt64 static_cast<Int64>
const Int64 mask = (1LL << 32) - 1;
void build(int r, int c, int* rt,
std::vector<Int64>& P) {
std::sort(P.begin(), P.end());
for(int i = 1, cur = 0; i <= r; ++i) {
rt[i] = rt[i - 1];
while(cur < P.size() && P[cur] >> 32 == i) {
rt[i] = insert(1, c, rt[i], P[cur] & mask);
++cur;
}
}
}
Int64 query(int c, int x1, int y1, int x2, int y2,
int* rt) {
if(x1 > x2 || y1 > y2)
return 0;
Int64 tot = asInt64(x2 - x1 + 1) * (y2 - y1 + 1);
int sub = query(1, c, rt[x1 - 1], rt[x2], y1, y2);
return tot - sub;
}
struct HashTable {
static const int modu = 400009, modv = 399989;
Int64 key[modu];
std::vector<Int64> P;
HashTable& operator=(const HashTable& rhs) {
memcpy(key, rhs.key, sizeof(key));
P.resize(rhs.P.size());
memcpy(P.data(), rhs.P.data(),
sizeof(Int64) * P.size());
return *this;
}
void insert(Int64 x, Int64 y) {
if(x <= 0 || y <= 0)
return;
Int64 k = x << 32 | y;
int ha = k % modu, hb = 1 + k % modv, cur = ha;
while(true) {
if(key[cur] == 0) {
key[cur] = k;
P.push_back(k);
}
if(key[cur] == k)
return;
cur += hb;
if(cur >= modu)
cur -= modu;
}
}
} LUT[3];
int rtA[size];
void solve11(int r, int c) {
build(r, c, rtA, LUT[0].P);
}
int rtB[size];
void solve12(int r, int c) {
const std::vector<Int64>& P = LUT[0].P;
LUT[1] = LUT[0];
for(int i = 0; i < P.size(); ++i) {
Int64 x = P[i] >> 32, y = P[i] & mask;
LUT[1].insert(x, y - 1);
}
build(r, c, rtB, LUT[1].P);
}
int rtC[size];
void solve21(int r, int c) {
const std::vector<Int64>& P = LUT[0].P;
LUT[2] = LUT[0];
for(int i = 0; i < P.size(); ++i) {
Int64 x = P[i] >> 32, y = P[i] & mask;
LUT[2].insert(x - 1, y);
}
build(r, c, rtC, LUT[2].P);
}
int rtD[size];
void solve22(int r, int c) {
const std::vector<Int64>& P = LUT[0].P;
for(int i = 0; i < P.size(); ++i) {
Int64 x = P[i] >> 32, y = P[i] & mask;
LUT[1].insert(x - 1, y);
LUT[1].insert(x - 1, y - 1);
}
build(r, c, rtD, LUT[1].P);
}
char buf[size];
int main() {
int r = read();
int c = read();
int m = read();
int q = read();
int x = read();
int y = read();
if(m)
scanf("%s", buf + 1);
LUT[0].insert(x, y);
int L = y, R = y, T = x, B = x;
for(int i = 1; i <= m; ++i) {
switch(buf[i]) {
case 'N':
--x;
break;
case 'S':
++x;
break;
case 'E':
++y;
break;
case 'W':
--y;
break;
}
LUT[0].insert(x, y);
L = std::min(L, y);
R = std::max(R, y);
T = std::min(T, x);
B = std::max(B, x);
}
solve11(r, c);
solve12(r, c);
solve21(r, c);
solve22(r, c);
for(int t = 1; t <= q; ++t) {
int x1 = read();
int y1 = read();
int x2 = read();
int y2 = read();
Int64 res = query(c, x1, y1, x2, y2, rtA) -
query(c, x1, y1, x2, y2 - 1, rtB) -
query(c, x1, y1, x2 - 1, y2, rtC) +
query(c, x1, y1, x2 - 1, y2 - 1, rtD);
if(x1 < T && y1 < L && x2 > B && y2 > R)
++res;
printf("%lld\n", res);
}
fprintf(stderr, "%d\n", tcnt);
for(int i = 0; i < 3; ++i)
fprintf(stderr, "%d\n",
static_cast<int>(LUT[i].P.size()));
return 0;
}
60 changes: 60 additions & 0 deletions Source/Competition/APIO/LOJ2567.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include <algorithm>
#include <cstdio>
typedef long long Int64;
#define asInt64 static_cast<Int64>
const int size = 505, mod = 1000000007;
int add(int a, int b) {
a += b;
return a < mod ? a : a - mod;
}
int A[size], B[size], C[size * 2], F[size * 2][size],
S[size * 2], SS[size * 2], inv[size];
int main() {
int n;
scanf("%d", &n);
int icnt = 0;
C[icnt++] = 0;
for(int i = 1; i <= n; ++i) {
scanf("%d%d", &A[i], &B[i]);
C[icnt++] = A[i] - 1;
C[icnt++] = B[i];
}
inv[1] = 1;
for(int i = 2; i <= n; ++i)
inv[i] = asInt64(mod - mod / i) *
inv[mod % i] % mod;
std::sort(C, C + icnt);
icnt = std::unique(C, C + icnt) - C;
F[0][0] = S[0] = 1;
SS[0] = 1;
for(int i = 1; i < icnt; ++i)
SS[i] = add(SS[i - 1], S[i]);
for(int i = 1; i <= n; ++i) {
int a =
std::lower_bound(C, C + icnt, A[i] - 1) -
C;
int b =
std::lower_bound(C, C + icnt, B[i]) - C;
for(int j = b; j > a; --j) {
int delta = C[j] - C[j - 1];
for(int k = std::min(delta, i); k >= 2;
--k) {
int addv = F[j][k - 1] *
asInt64(delta - k + 1) % mod *
inv[k] % mod;
F[j][k] = add(F[j][k], addv);
S[j] = add(S[j], addv);
}
int addv =
SS[j - 1] * asInt64(delta) % mod;
F[j][1] = add(F[j][1], addv);
S[j] = add(S[j], addv);
}
SS[0] = 1;
for(int j = 1; j < icnt; ++j)
SS[j] = add(SS[j - 1], S[j]);
}
int res = SS[icnt - 1] - 1;
printf("%d\n", res < 0 ? res + mod : res);
return 0;
}
59 changes: 59 additions & 0 deletions Source/Competition/APIO/LOJ2886.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#include <bitset>
#include <cstdio>
#include <cstring>
typedef long long Int64;
const int size = 2005, sizA = 105;
Int64 S[size];
std::bitset<sizA> F[sizA];
Int64 solveA(int n, int p, int A, int B) {
Int64 res = 0;
for(int i = p; i >= 0; --i) {
Int64 st = res + (1LL << i) - 1;
memset(F, 0, sizeof(F));
F[0][0] = true;
for(int j = 1; j <= n; ++j)
for(int k = 0; k < j; ++k)
if(((S[j] - S[k]) | st) == st)
F[j] |= F[k] << 1;
bool flag = true;
for(int k = A; k <= B; ++k)
if(F[n][k]) {
flag = false;
break;
}
if(flag)
res = st + 1;
}
return res;
}
int G[size];
Int64 solveB(int n, int p, int B) {
Int64 res = 0;
for(int i = p; i >= 0; --i) {
Int64 st = res + (1LL << i) - 1;
memset(G, 0x3f, sizeof(G));
G[0] = 0;
for(int j = 1; j <= n; ++j)
for(int k = 0; k < j; ++k)
if(((S[j] - S[k]) | st) == st)
G[j] = std::min(G[j], G[k] + 1);
if(G[n] > B)
res = st + 1;
}
return res;
}
int main() {
int n, A, B;
scanf("%d%d%d", &n, &A, &B);
for(int i = 1; i <= n; ++i) {
int x;
scanf("%d", &x);
S[i] = S[i - 1] + x;
}
int p = 0;
while((1LL << p) < S[n])
++p;
printf("%lld\n", A > 1 ? solveA(n, p, A, B) :
solveB(n, p, B));
return 0;
}
Loading

0 comments on commit bc36dcb

Please sign in to comment.