-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
728 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
\chapter{标准库应用} | ||
\minitoc | ||
\input{STL/bitset} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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以内计算。} | ||
|
||
为了支持负数,下面算法均使用补码表示。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
Oops, something went wrong.