icpclib - arosh/arosh.github.com GitHub Wiki
$ sudo apt-get install build-essential vim-nox gedit g++ clang++ valgrind gdb
# CapsLockããŒã远å ã®CtrlããŒãšããŠäœ¿ã
$ dconf write /org/gnome/desktop/input-sources/xkb-options "['ctrl:nocaps']"
# CapsLockããŒã®åäœãããã©ã«ãã«æ»ã
$ dconf reset /org/gnome/desktop/input-sources/xkb-options
UbuntuTips/Desktop/HowToSetCapsLockAsCtrl - Ubuntu Japanese Wiki
set nu " number
syntax on
filetype plugin indent on
set ts=2 sw=2 sts=2 et " tabstop shiftwidth softtabstop expandtab
set is hls ic " incsearch hlsearch ignorecase
set sm mat=0 " showmatch matchtime=0
" BackSpaceã§ãªãã§ãæ¶ã (ãã¶ãäžèŠ)
set backspace=indent,eol,start
CXXFLAGS=-D_GLIBCXX_DEBUG -std=c++11 -Wall -Wextra -Wshadow -g -fsanitize=address
# é床ãé
ããšãã¯-D_GLIBCXX_DEBUGãå€ããŠ-O2ãä»ãã
# -O1以äžã®ãšãã¯ïŒããŒã«ã«ãã£ãŠã¯-fno-omit-frame-pointerãå¿
èŠ
ãã®ä»æçšãªãªãã·ã§ã³é 1 2 3 4
:make ãã«ããã
:cn 次ã®ãšã©ãŒç®æã«ç§»å
:cc ãšã©ãŒãå確èª
$ g++ -g ... # ãããã°ã·ã³ãã«ãä»ããŠã³ã³ãã€ã«
$ gdb ./main
(gdb) r < a.in > a.out # å®è¡
(gdb) bt # backtraceã調ã¹ã
(gdb) f 3ãšã4ãšã # 颿°ãã¬ãŒã ã®ç§»å
(gdb) l # åšèŸºã®ãœãŒã¹ã³ãŒãã®è¡šç€º
(gdb) p x # 倿°ã®è¡šç€º
- ã¡ã¢åååž°ã®ãã£ãã·ã¥ã®åç §æã«ç¯å²å€ãåç §ããŠãã (assertå ¥ããšãïŒ)
- ã¹ã¿ãã¯ãªãŒããŒãã㌠(巚倧ãªéç倿°, ååž°ããã (shared_ptrã®ãã¹ãã©ã¯ã¿ã«ã泚æïŒ),
ulimit -s
ããã)
template <class T, class U>
T lexical_cast(const U& from) {
T to;
stringstream ss;
ss << from; ss >> to;
return to;
}
// iostreamãé
ããšã㯠std::ios::sync_with_stdio(false); ãèšå®ã
// std::endl ã®ä»£ããã« '\n' ã䜿ã (#define endl '\n')
// std::cin.tie(nullptr); ã¯ããŸã广ããªããããæ°ããã
printf("%0*d", 4, 123); // => 0123
cout << setw(4) << setfill('0') << 123 << endl; // => 0123
cout.setf(ios::fixed); cout.precision(10);
// remove, unique, rotate
vector<int> v = { 1, 1, 2, 3, 5 };
v.erase(remove(v.begin(), v.end(), 3), v.end());
v.erase(unique(v.begin(), v.end()), v.end());
v.erase(v.begin() + 2); // v[2]ã ãæ¶ã (v.end()äžèŠ)
rotate(v.begin(), v.begin() + 2, v.end()); // v[2]ãæåã«æ¥ã
// mapãsetã®æ¯èŒé¢æ°
struct Node {
int fst, snd;
Node(int f, int s) : fst(f), snd(s) { }
};
struct NodeCmp {
bool operator()(const Node& a, const Node& b) {
if(a.fst != b.fst) return a.fst < b.fst;
return a.snd < b.snd;
}
};
set<Node, NodeCmp> s;
// map#[]ã«map#sizeã¯ãã¡ããŒãã¿ã€ã
std::map<int, int> dict;
dict[123] = dict.size(); // dict[123] = 0 or 1
vector<string> splitAll(string s, string t) {
vector<string> v;
for(int p = 0; (p = s.find(t)) != string::npos; ) {
v.push_back(s.substr(0, p));
s = s.substr(p + t.size());
}
v.push_back(s);
return v;
}
string replaceAll(string s, string f, string t) {
string r;
for(int p = 0; (p = s.find(f)) != string::npos; ) {
r += s.substr(0, p) + t;
s = s.substr(p + f.size());
}
return r + s;
}
__builtin_popcount(b); // (1 << 1) | (1 << 3) => 2
// 0ãå
¥ãããšãã±ã³ïŒïŒïŒ
__builtin_ctz(b); // (1 << 1) | (1 << 3) => 1
31 - __builtin_clz(b); // (1 << 1) | (1 << 3) => 3
// unsigned long long ãªå Žåã¯
__builtin_popcountll();
__builtin_ctzll();
__builtin_clzll();
// å·Šã·ããã®ç©Žåãã¯0ã§ããããšãä¿èšŒããã
// unsignedã®å³ã·ããã®ç©Žåãã¯0ã§ããããšãä¿èšŒããã
// signedã®å³ã·ããã®ç©Žåãã¯0ã§ããããšãä¿èšŒãããªã
S = S & ~(1 << k); // kçªç®ã®ãããã®æ¶å»
S = S & -S; // æãå³ã®1ããã
S = -S & (S + 1); // æãå³ã®0ããã
// éåã®éšåéåã®åæããµã€ãºkã®éåã®åæ â è»æ¬ã®p.144ã«èŒã£ãŠããã©ããåããã
- æ¡ä»¶ãæºããæå€§å€ ⊠[lb, ub) ⊠assert(check(lb) && !check(ub))
- æ¡ä»¶ãæºããæå°å€ ⊠(lb, ub] ⊠assert(!check(lb) && check(ub))
int search_max() {
int lb = 0, ub = N;
while(ub - lb > 1) {
int mid = (lb + ub) / 2;
(check(mid) ? lb : ub) = mid;
}
return lb;
}
int search_min() {
int lb = -1, ub = N - 1;
while(ub - lb > 1) {
int mid = (lb + ub) / 2;
(check(mid) ? ub : lb) = mid;
}
return ub;
}
éå·®æ°åãäœãïŒç¬Šå·ãé転ããäœçœ®ãæ¢ãã°ããããã (åè)
struct UnionFind {
vector<int> data;
UnionFind(int v) : data(v, -1) {}
int root(int x) {
return data[x] < 0 ? x : data[x] = root(data[x]);
}
bool same(int x, int y) {
return root(x) == root(y);
}
int size(int x) {
return -data[root(x)];
}
void merge(int x, int y) {
x = root(x), y = root(y);
if (x != y) {
if (size(y) > size(x))
swap(x, y);
data[x] += data[y];
data[y] = x;
}
}
};
- åºéã®åãããã³å€ã®æŽæ°ã O(log n) ã§è¡ãã
- ç¯ç¹ã¯ãã¹ãŠã®å€ã®åèšãæã€ããšã«ãªãã®ã§ãæ¡ããµãããªããã©ããæ€èšãã (typedefããã»ããããããïŒ)
- è»æ¬ã®å®è£ ã¯éåºéã ãããã®å®è£ ã¯åéåºéã§ãã
struct BIT {
int N;
vector<int> data;
BIT(int n) : N(n), data(n + 1, 0) { }
void add(int a, int w) {
++a;
for(int x = a; x <= N; x += x & -x) {
data[x] += w;
}
}
int sum(int a) {
int ret = 0;
for(int x = a; x > 0; x -= x & -x) {
ret += data[x];
}
return ret;
}
};
bit0.add(l, -x * l);
bit1.add(l, x);
bit0.add(r, x * r);
bit1.add(r, -x);
bit0.sum(r) + r*bit1.sum(r) - bit0.sum(l) - l*bit1.sum(l);
- ç¯ç¹ã®æ°ã¯N-1å
- åæå€ãã©ããããæ€èšããã(ç¯å²å€ã®å¯ŸåŠãããã®ãå«ãªã®ã§)
const int INF = (int)1e9;
struct RMQ {
vector<int> data;
int N;
RMQ(int size) {
N = 1;
while(N < size) N *= 2;
data.assign(2*N - 1, INF);
}
// 0ãªãªãžã³ã§kçªç®ã®èŠçŽ ãaã«å€æŽãã
void update(int k, int a) {
k += N - 1; // èã«ç§»å
data[k] = a;
while(k > 0) {
k = (k - 1)/2;
data[k] = min(data[2*k + 1], data[2*k + 2]);
}
}
// minimum [a, b)
int minimum(int a, int b) {
return minimum_sub(a, b, 0, 0, N);
}
int minimum_sub(int a, int b, int k, int l, int r) {
if(r <= a || b <= l) return INF;
if(a <= l && r <= b) return data[k];
return min(minimum_sub(a, b, 2*k + 1, l, (l + r)/2),
minimum_sub(a, b, 2*k + 2, (l + r)/2, r));
}
};
struct SegTree {
int N;
vector<ll> data_add;
vector<ll> data_min;
SegTree(int size) {
N = 1;
while(N < size) N *= 2;
data_add.assign(2*N - 1, 0LL);
data_min.assign(2*N - 1, 0LL);
}
void add(int a, int b, ll x, int k, int l, int r) {
if(r <= a || b <= l) return;
if(a <= l && r <= b) {
data_add[k] += x;
while(k > 0) {
k = (k - 1) / 2;
data_min[k] = min(data_min[2*k + 1] + data_add[2*k + 1],
data_min[2*k + 2] + data_add[2*k + 2]);
}
}
else {
add(a, b, x, 2*k + 1, l, (l + r)/2);
add(a, b, x, 2*k + 2, (l + r)/2, r);
}
}
ll minimum(int a, int b, int k, int l, int r) {
if(r <= a || b <= l) return INF;
if(a <= l && r <= b) {
return data_min[k] + data_add[k];
}
else {
return min(minimum(a, b, 2*k + 1, l, (l + r)/2),
minimum(a, b, 2*k + 2, (l + r)/2, r)) + data_add[k];
}
}
};
-
sqrtN
ã®èª¿æŽã«ãã£ãŠé床ãçµæ§å€ããã2*sqrt(N)ããããè¯ãæ°ããã -
update
ãšquery
ã¯ããããã¯ãèŠããããªå Žå (Large) ãšãããã¯ã®å éšã ãã®å Žå (Small) ã®åèš4éãã«å¯Ÿå¿ããããšã確ããããšè¯ã -
N
ãå°ããªã±ãŒã¹ã ãšç¯å²ã«å¯Ÿããæäœã®ãã¹ããè¡ãããªãã®ã§ïŒãµã³ãã«ãã¹ãã®ãšãã¯sqrtN = 2
ãšããã¹ã
const int sqrtN = 400;
struct SqrtDecomposition {
int N, K;
vector<int> data;
vector<int> addpart;
vector<int> addall;
SqrtDecomposition(int n) : N(n) {
K = (N + sqrtN - 1) / sqrtN;
data.assign(K * sqrtN, 0);
addpart.assign(K, 0);
addall.assign(K, 0);
}
void put(int a, int b, int value) {
for(int k = 0; k < K; ++k) {
int l = k * sqrtN, r = (k + 1) * sqrtN;
if(r <= a || b <= l) continue;
if(a <= l && r <= b) {
addall[k] += value;
}
else {
for(int i = max(a, l); i < min(b, r); ++i) {
data[i] += value;
addpart[k] += value;
}
}
}
}
int get(int a, int b) {
int ret = 0;
for(int k = 0; k < K; ++k) {
int l = k * sqrtN, r = (k + 1) * sqrtN;
if(r <= a || b <= l) continue;
if(a <= l && r <= b) {
ret += addall[k] * sqrtN + addpart[k];
}
else {
for(int i = max(a, l); i < min(b, r); ++i) {
ret += data[i] + addall[k];
}
}
}
return ret;
}
};
- èŠçŽ ãæŽæ°ãããªã
- ã¯ãšãªã®å èªã¿ãå¯èœ
- åºé [L,R] ã®çµæãã [L-1, R], [L+1, R], [L, R-1], [L, R+1] ã®çµæã容æã«åŸããã
queries.sort(key=lambda x: (x.L // S, x.R))
i, j = 0, -1
for l, r, index in queries:
while i < l: remove(i++) // [i, j] -> [i+1, j]
while i > l: add(--i) // [i, j] -> [i-1, j]
while j < r: add(++j) // [i, j] -> [i, j+1]
while j > r: remove(j--) // [i, j] -> [i, j-1]
ans[index] = answer
http://pekempey.hatenablog.com/entry/2016/01/23/185143 https://twitter.com/yosupot/status/745520261819031552
- ãã¹ãŠã®èŸºã1床ã ãéãéè·¯ â ãªã€ã©ãŒéè·¯
- ãã¹ãŠã®é ç¹ã1床ã ãéãéè·¯ â ããã«ãã³éè·¯
- å§ç¹ãšçµç¹ãåã â ã°ã©ããé£çµã§ããã¹ãŠã®é ç¹ã®æ¬¡æ°ãå¶æ°
- å§ç¹ãšçµç¹ãç°ãªã â ã°ã©ããé£çµã§ãå§ç¹ãšçµç¹ã®æ¬¡æ°ã奿°ã§ããã®ä»ã¯å¶æ°
- å§ç¹ãšçµç¹ãåã â ã°ã©ããé£çµã§ããã¹ãŠã®é ç¹ã«ã€ããŠå ¥æ¬¡æ°ãšåºæ¬¡æ°ãåã
- å§ç¹ãšçµç¹ãç°ãªã â ïŒ
- Primã¯æå°å šåæšãæ±ããã¢ã«ãŽãªãºã
- Kruskalã¯æå°å šåæ£®ãæ±ããã¢ã«ãŽãªãºã
struct Edge {
int to, cost;
Edge(int to_, int cost_) : to(to_), cost(cost_) { }
};
struct State {
int pos, cost;
State(int pos_, int cost_) : pos(pos_), cost(cost_) { }
bool operator <(const State &s) const {
return cost > s.cost;
}
};
vector<int> shortest_path(const vector<vector<Edge>> &G, const int src) {
const int n = G.size();
vector<int> d(n, INF);
priority_queue<State> Q;
Q.emplace(src, 0);
d[src] = 0;
while(!Q.empty()) {
State s = Q.top(); Q.pop();
if(s.cost > d[s.pos]) continue;
for(Edge e : G[s.pos]) {
if(d[e.to] > s.cost + e.cost) {
d[e.to] = s.cost + e.cost;
Q.emplace(e.to, d[e.to]);
}
}
}
return d;
}
d[j] = d[i] + cost[i][k];
ãšæŽæ°ãããæã« prev[j] = i;
ã¿ãããªããšãããã°ãããè»æ¬p.98ãåç
§
è² ã®èŸºããã£ãŠãåäœãããè² ã®éè·¯ã®æ€åºãè¡ãããè»æ¬p.95ãåç §ã
-
d[i][i] = 0
ã«ããªããšåäœããªã - è² èŸºããããšãã¯ãããããšã€ãããG[a][b]=â, G[a][c]=â, G[b][c]=-1ã¿ãããªãšãã« G[a][c]=min(G[a][c],G[a][b]+G[b][c]) ãšãããš G[a][c]<â ãšãªã£ãŠããŸãã®ã§ãminããšãåã« G[a][b]!=â, G[b][c]!=â ã確èªããããšïŒïŒã
-
d[i][i] < 0
ã«ãªã£ãŠããã â è² ã®éè·¯ãååšãã
v = 0 ããã¯ããŸããv = 0ã§çµãããšã
const int MAX_N = 16;
const int INF = (int)1e9;
int d[MAX_N][MAX_N];
int dp[MAX_N][1 << MAX_N];
int tsp(int v, int b) {
if(dp[v][b] != -1) return dp[v][b];
// å
šãŠã®é ç¹ãçµç±ããæ»ã£ãŠãã
if(b == (1 << N) - 1 && v == 0) return 0;
int res = INF;
for(int i = 0; i < N; i++) {
if(b & (1 << i)) continue;
res = min(res, tsp(i, b | (1 << i)) + d[v][i]);
}
return dp[v][b] = res;
}
int solve() {
memset(dp, -1, sizeof(dp));
return tsp(0, 0); // åŒã³åºã泚æïŒ
}
struct Scc {
const int V; // é ç¹æ°
vector<vector<int> > G, revG; // ã°ã©ãã®é£æ¥ãªã¹ã衚çŸãšããã®éã°ã©ã
vector<int> order; // scc()ãåŒã¶ãšãããããžã«ã«é åºãå
¥ã
vector<int> vs; // åž°ãããé åº
vector<bool> used; // STL泚æ
Scc(int v) : V(v), G(v), revG(v), order(v), used(v) { }
void add_edge(int from, int to) {
G[from].push_back(to);
revG[to].push_back(from);
}
void dfs(int v) {
used[v] = true;
for(int to : G[v]) {
if(used[to] == false) dfs(to);
}
vs.push_back(v);
}
void rdfs(int v, int k) {
used[v] = true;
order[v] = k;
for(int to : revG[v]) {
if(used[to] == false) rdfs(to, k);
}
}
// @return 匷é£çµæåãæœ°ããŠDAGãäœã£ããšãã®é ç¹æ°
int compute() {
vs.clear();
used.assign(V, false);
for(int i = 0; i < V; i++) {
if(used[i] == false) dfs(i);
}
int k = 0;
reverse(vs.begin(), vs.end());
used.assign(V, false);
for(int v : vs) {
if(used[v] == false) rdfs(v, k++);
}
return k;
}
};
O(V+E)
vector<int> topological_sort(const vector<vector<int>> &G) {
const int N = G.size();
vector<int> indeg(N, 0);
for(auto &&vs : G) {
for(int v : vs) {
indeg[v]++;
}
}
queue<int> Q;
for(int i = 0; i < N; ++i) {
if(indeg[i] == 0) Q.push(i);
}
vector<int> ret;
while(!Q.empty()) {
int v = Q.front(); Q.pop();
ret.push_back(v);
for(int u : G[v]) {
indeg[u]--;
if(indeg[u] == 0) Q.push(u);
}
}
return ret;
}
struct LCA {
int N, logN; // logN == ceil(lg(N))
vector<vector<int>> G;
vector<int> depth;
// vããæ ¹ã®æ¹åã«2^kåç»ã£ããšãã®ããŒã parent[k][v]
vector<vector<int>> parent;
LCA(int size) : N(size), G(size), depth(size) {
logN = 0;
for(int x = 1; x < N; x *= 2) logN++;
parent.assign(max(logN, 1), vector<int>(N));
}
// ã©ã¡ããæ ¹ã§ãã£ãŠãOK
void add_edge(int u, int v) {
G[u].push_back(v);
G[v].push_back(u);
}
void dfs(int v, int par, int dep) {
depth[v] = dep;
parent[0][v] = par;
for(int next : G[v]) {
if(next != par) dfs(next, v, dep + 1);
}
}
void build(int root) {
dfs(root, -1, 0);
for(int k = 1; k < logN; k++) {
for(int v = 0; v < N; v++) {
if(parent[k - 1][v] == -1) parent[k][v] = -1;
else parent[k][v] = parent[k - 1][parent[k - 1][v]];
}
}
}
int lca(int u, int v) {
if(depth[u] > depth[v]) swap(u, v); // vã®ã»ããæ·±ããªã
// uãšvã®æ·±ããåãã«ãªããŸã§vãæ ¹ã®æ¹åã«ç§»åãã
for(int k = 0; k < logN; k++) {
if(((depth[v] - depth[u]) >> k) & 1) {
v = parent[k][v];
}
}
if(u == v) return u;
for(int k = logN - 1; k >= 0; k--) {
if(parent[k][u] != parent[k][v]) {
u = parent[k][u];
v = parent[k][v];
}
}
return parent[0][u];
}
};
struct LowLink {
const int N;
vector<vector<int>> G;
vector<bool> vis;
vector<int> ord, parent, low;
LowLink(int size) : N(size), G(size), vis(size, false), ord(size), parent(size), low(size) { }
void add(int a, int b) {
G[a].push_back(b); G[b].push_back(a);
}
void dfs(int v, int &k) {
ord[v] = low[v] = k++;
vis[v] = true;
for(int u : G[v]) {
if(!vis[u]) {
parent[u] = v;
dfs(u, k);
low[v] = min(low[v], low[u]);
}
else if(u != parent[v]) {
low[v] = min(low[v], ord[u]);
}
}
}
void compute() {
int k = 0;
dfs(0, k);
}
vector<pair<int, int>> bridge() {
compute();
vector<pair<int, int>> ret;
for(int i = 0; i < N; ++i) {
if(ord[parent[i]] < low[i]) ret.emplace_back(parent[i], low[i]);
}
return ret;
}
vector<int> articulation() {
compute();
vector<int> ret;
int c = 0;
for(int i = 1; i < N; ++i) {
int p = parent[i];
if(p == 0) ++c;
else if(ord[p] <= low[i]) ret.push_back(p);
}
if(c >= 2) ret.push_back(0);
sort(ret.begin(), ret.end());
ret.erase(unique(ret.begin(), ret.end()), ret.end());
return ret;
}
};
- èªå·±ã«ãŒãïŒå€é蟺ãæããªãç¡åã°ã©ãGã«iâjã®èŸºããããšãã«(i,j)èŠçŽ ã1ãšãªãè¡åã飿¥è¡åAãšãããA^nã®(i,j)èŠçŽ ã¯é·ãnã§iâjã«è¡ãçµè·¯æ° (ç¹ã«(i,i)èŠçŽ ã¯éè·¯)
- è¡åæšå®çïŒé ç¹iã®æ¬¡æ°ã察è§èŠçŽ (i,i)ã«æã€è¡åãæ¬¡æ°è¡åDãšãããã©ãã©ã·ã¢ã³è¡åL=D-Aã®ä»»æã®äœå åã¯çããïŒãã®å€ã¯å šåæšã®åæ°ã§ãã (äŸ)
const int INF = (int)1e9;
struct Edge {
int to, cap, rev;
Edge(int to_, int cap_, int rev_) :
to(to_), cap(cap_), rev(rev_) { }
};
struct FordFulkerson {
const int V;
vector<vector<Edge> > G;
vector<bool> used;
FordFulkerson(int v) : V(v), G(v), used(v) { }
void add_edge(int from, int to, int cap) {
G[from].emplace_back(to, cap, G[to].size());
G[to].emplace_back(from, 0, G[from].size() - 1);
}
int find_flow(int v, int t, int f) {
if(v == t) return f;
used[v] = true;
for(Edge &e : G[v]) {
if(used[e.to] == false && e.cap > 0) {
int d = find_flow(e.to, t, min(f, e.cap));
if(d > 0) {
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
int max_flow(int s, int t) {
int flow = 0;
while(true) {
used.assign(V, false);
int f = find_flow(s, t, INF);
if(f == 0) return flow;
flow += f;
}
}
};
struct Matching {
int N, M;
vector<vector<int>> G;
vector<int> match;
vector<bool> used;
Matching(int n, int m) : N(n), M(m), G(n + m) {}
void add_edge(int u, int v) {
G[u].push_back(v);
G[v].push_back(u);
}
bool dfs(int v) {
used[v] = true;
for (int u : G[v]) {
int w = match[u];
if (w < 0 || (!used[w] && dfs(w))) {
match[v] = u;
match[u] = v;
return true;
}
}
return false;
}
int max_match() {
int res = 0;
match.assign(N + M, -1);
for (int v = 0; v < N + M; ++v) {
if (match[v] < 0) {
used.assign(N + M, false);
if (dfs(v)) res++;
}
}
return res;
}
};
å²ãåœãŠåé¡ â ãœãŒãããã ãã ã£ããããŸãããïŒ
ãšãã¯ãããã®ãLPãšã°ã©ããšå®åŒåããåç §ïŒ
- æççµè·¯åé¡ãã䜿ã蟺ã®éã¿ã®åèšãæå°åãããIPãšããŠå®çŸ©ãã
- é ã®è¯ãç·©åãå°å ¥ããŠLPã«ãã
- å察ããšããšçã®åé¡ã«ãªã
ãããŸã圹ã«ç«ããªãããã ãïŒäžå¿æšæºåœ¢ãèŒããŠãã
- äž»åé¡
max. c'x, s.t. (1) Ax <= b, (2) x >= 0
- å察åé¡
min. b'y, s.t. (3) A'y >= c, (4) y >= 0
- æ¬åœã«LL(1)ïŒ æéããããªãBNFã¯æžããã»ããè¯ãã§ãã
- å³ããèªããšLL(1)ã®ãã¿ãŒã³
typedef string::const_iterator iter;
int expr(iter& p);
int term(iter& p);
int factor(iter& p);
int number(iter& p);
int expr(iter& p) {
int r = term(p);
while(true) {
if(*p == '+') {
++p;
int rs = term(p);
r += rs;
}
else if(*p == '-') {
++p;
int rs = term(p);
r -= rs;
}
else {
break;
}
}
return r;
}
int term(iter& p) {
int r = factor(p);
while(true) {
if(*p == '*') {
p++;
int rs = factor(p);
r *= rs;
}
else if(*p == '/') {
p++;
int rs = factor(p);
r /= rs;
}
else {
break;
}
}
return r;
}
int factor(iter& p) {
if(*p == '(') {
++p; // skip (
int r = expr(p);
++p; // skip )
return r;
}
return number(p);
}
int number(iter& p) {
int r = 0;
while(isdigit(*p)) {
r *= 10;
r += *p -'0';
p++;
}
return r;
}
- BASE ... 29, 53, 131, 257
- MOD ... 636094623231363827, 348051774975651917, 140814840257324803, 71777214294589669
enum FACE { TOP, FRONT, RIGHT, LEFT, BACK, BOTTOM }; // 1..6
typedef array<int, 6> Dice;
FACE tbl[6][4] = {
{ TOP, BACK, BOTTOM, FRONT },
{ TOP, RIGHT, BOTTOM, LEFT },
{ TOP, FRONT, BOTTOM, BACK },
{ TOP, LEFT, BOTTOM, RIGHT },
{ FRONT, RIGHT, BACK, LEFT },
{ FRONT, LEFT, BACK, RIGHT }
};
enum MOVE { TOP_TO_BACK, TOP_TO_RIGHT, TOP_TO_FRONT,
TOP_TO_LEFT, FRONT_TO_RIGHT, FRONT_TO_LEFT };
void rotate(Dice &d, FACE t[4]) {
int tmp = d[t[3]];
d[t[3]] = d[t[2]]; d[t[2]] = d[t[1]]; d[t[1]] = d[t[0]]; d[t[0]] = tmp;
}
vector<Dice> generate_all(Dice dice) {
vector<Dice> res;
for(int i = 0; i < 6; ++i) {
for(int j = 0; j < 4; ++j) {
res.emplace_back(dice);
rotate(dice, tbl[FRONT_TO_RIGHT]);
}
if(i % 2 == 0) rotate(dice, tbl[TOP_TO_BACK]);
else rotate(dice, tbl[TOP_TO_RIGHT]);
}
return res;
}
æ£æ¹è¡åAã®ç¹æ§å€é åŒãg(t)ãšãããšã g(A)=O
- if rank(A) = rank(A|b) = n â å¯äžè§£ããã€
- elif rank(A) = rank(A|b) â è§£ãè€æ°ãã€
- else â è§£ãªã
- rank = æãåºããè¡ããåæ°
- ãããŸãè¡åã«ã€ããŠæ·±ãèãããåã«é£ç«æ¹çšåŒãšããŠèããã»ããè¯ãã
- é¢å¿ã®ç¡ãéšåã®è§£ã«ã€ããŠã¯è§£ãäžæ§ã«å®ãŸãããã«é©åœã«ä¿æ°ãå ¥ãã
- åãªãDPã§è§£ããªããïŒ å埩æ³ã«ããåè§£æ³ãæããŠã¿ã
bool EQ(double a, double b) { return abs(a - b) < 1e-8; }
typedef vector<double> Vec;
typedef vector<Vec> Mat;
bool solve_mat(Mat B, Vec& x) {
const int N = B.size();
for(int i = 0; i < N; i++) {
int pivot = i;
for(int r = i + 1; r < N; r++) {
if(abs(B[r][i]) > abs(B[pivot][i])) pivot = r;
}
B[i].swap(B[pivot]);
if(EQ(B[i][i], 0)) return false;
// æ¬æ¥ãªãã°0ã1ã«ãªãèŠçŽ ã®èšç®ããµãã
for(int j = i + 1; j < N + 1; j++) B[i][j] /= B[i][i];
for(int r = 0; r < N; r++) {
if(r == i) continue;
double mul = B[r][i];
for(int j = i + 1; j < N + 1; j++) {
B[r][j] -= B[i][j] * mul;
}
}
}
x.resize(N);
for(int i = 0; i < N; i++) x[i] = B[i][N];
return true;
}
ãè¡ã®å ¥ãæ¿ãã¯-1åãã«æ°ãã€ããªããåºæ¬å€åœ¢ã§äžè§åããŠå¯Ÿè§èŠçŽ ã®ç©ããšã
double simpson(double L, double R, int div = 1) {
const double h = (R - L) / (2 * div);
double s = 0.0, t = 0.0;
for(int i = 1; i <= 2 * div - 3; i += 2) {
s += f(L + h*i); t += f(L + h*(i + 1));
}
return h / 3 * (f(L) + f(R) + 4*(s + f(R - h)) + 2*t);
}
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97
- aãšbãäºãã«çŽ := gcd(a,b)=1
- æŽæ°a,bãäºãã«çŽ ã§ããã° ax+by=1 ãæºããæŽæ°x,yãååšãããax+by=gcd(a,b) ãæºããa,bã¯extgcdã§æ±ãããã
- aãšb1ãäºãã«çŽ && aãšb2ãäºãã«çŽ => aãšb1*b2ã¯äºãã«çŽ
- aãšbãäºãã«çŽ <=> 2a-1ãš2b-1ãäºãã«çŽ
- é£ç¶ãã2ã€ã®æŽæ°ã¯äºãã«çŽ âµgcd(n,n+1)=gcd(n,(n+1)%n)=gcd(n,1)=1
axâ¡1 (mod m)
ãæºããx
ãa
ã®éå
ãšãããax=1 (mod m)
ã®ãšãax=1+km
ãæºããk
ãååšããã®ã§ïŒax-km=1
ãšãªãx
ïŒk
ãæ¢ãã°è¯ãã
MODãçŽ æ°ãªãïŒinv(n)=pow(n,m-2)
(ãã§ã«ããŒã®å°å®ç)
int extgcd(int a, int b, int &x, int &y) {
int d = a;
if (b != 0) {
d = extgcd(b, a % b, y, x);
y -= (a / b) * x;
} else {
x = 1; y = 0;
}
return d;
}
int mod_inv(int a, int m) {
int x, y;
extgcd(a, m, x, y);
return (m + x % m) % m;
}
pãçŽ æ°ãpãšnãäºãã«çŽ ã§ãããšããn^(p-1)=1 (mod p)
Ï(n) := i <- 1..n ã«ã€ã㊠gcd(n,i)==1 ã®åæ°
TODO: ã©ã¡ãããšãããšO(ân)ã®å®è£ ã®ã»ããã»ãã⊠(è»æ¬p.261)
vector<int> euler(int n) {
vector<int> res(++n);
for(int i = 0; i < n; i++) res[i] = i;
for(int i = 2; i < n; i++) {
if(res[i] == i) {
for(int j = i; j < n; j += i)
res[j] = res[j]/i*(i-1);
}
}
return res;
}
x^k % m ãèšç®ãããm^2 < INT_MAX ãªãã°æ¡ããµãããªã
ll pow_mod(ll x, ll y) {
ll res = 1;
for(; y > 0; y >>= 1, (x *= x) %= MOD) {
if(y & 1) (res *= x) %= MOD;
}
return res;
}
ll lcm_many(const vector<ll> &v) {
vector<int> maxexp(MAX + 1, 0);
for(ll item : v) {
ll s = item;
for(ll d = 2; d * d <= s; d++) {
int k = 0;
while (s % d == 0) {
s /= d;
k++;
}
maxexp[d] = max(maxexp[d], k);
}
maxexp[s] = max(maxexp[s], 1);
}
ll lcm = 1;
for (ll i = 2; i <= MAX; ++i) {
lcm *= pow_mod(i, maxexp[i]);
lcm %= MOD;
}
return lcm;
}
ll lcm1ton(const int n) {
ll lcm = 1;
vector<bool> vis(n + 1, false);
for(int i = 2; i <= n; ++i) {
if(vis[i]) continue;
ll num = i;
while(num * i <= n) num *= i;
for(int j = i * i; j <= n; j += i)
vis[j] = true;
(lcm *= num) %= MOD;
}
return lcm;
}
const int MAX_N = 10;
const int MAX_K = 10;
int dp[MAX_N][MAX_K];
int comb(int n, int k) {
if(k < 0 || k > n) return 0;
if(n == 0) return 1;
if(dp[n][k] > 0) return dp[n][k];
return dp[n][k] = comb(n-1, k-1) + comb(n-1, k);
}
int main() {
memset(dp, 0, sizeof(dp));
}
å°ããé ã«åæ°ãåæãã
void stern_brocot(int ax = 0, int ay = 1, int bx = 1, int by = 0) {
int mx = ax + bx; // åå
int my = ay + by; // 忝
// äœããã®å¶éãããã
stern_brocot(ax, ay, mx, my);
// äœããã
stern_brocot(mx, my, bx, by);
}
- E[X] = sum(x_i*p_i)
- æåŸ å€ã®åã¯åã®æåŸ å€ E[X+Y] = E[X] + E[Y]
- XãšYãç¬ç«ãªäºè±¡ã®ç¢ºç倿°ãªã E[X*Y] = E[X]*E[Y]
ç³ã®å±±ãNåãããããããA[i]åã®ç³ãå«ãã§ããŸããAliceãšBobã¯äº€äºã«ç©ºã§ãªãå±±ã1ã€éžã³ããããã1ã€ä»¥äžã®ç³ããšããŸããAliceã®çªããã¯ããŸããæåŸã®ç³ãåã£ãã»ããåã¡ã§ããäž¡è ãæåãå°œãããå Žåãåã€ã®ã¯ã©ã¡ãã§ããïŒ
- A[1] ^ A[2] ^ ... A[N] != 0 â å æ (Alice) ã®åã¡
- A[1] ^ A[2] ^ ... A[N] == 0 â åŸæ (Bob) ã®åã¡
- å岿°: Nåã®åºå¥ãã§ããªãåç©ãNå以äžã®ã°ã«ãŒã(é çªã¯èããªã)ã«åãããšãã®åãæ¹ã®æ° (解説)
- ã«ã¿ã©ã³æ°: N+1åã®èãæã€äºåæšã®äœãæ¹ã®ç·æ°
-
dp[i+1][j]=Σ_{k=a}^b dp[i][j-k]
ã¿ãããªåœ¢åŒã§O(NM^2)
ã®ãšãã¯çޝç©åã§O(NM)
ã«èœãšããããšãå€ã
- 20! < 2^63
- 4*4000*4000(B) = 6.4(MB)
- ã©ã€ãã©ãªãæã£ãŠããªãå¹Ÿäœ â æçŽã«æ¹çšåŒãããŠãŠã¿ããšããŸããããã
- äœããã®å¶çŽãã€ããæååãªãæ°å â ãªãŒãããã³
- ãããæ³ãããããšãæ³ãpriority_queueãåžãå調å¢å ãå調æžå°
- åé¡ãããèªããš â äºéšã°ã©ããæšãDAG
- äºéšã°ã©ã (è»æ¬p.198)
- |æå°èŸºã«ããŒ(ãã¹ãŠã®é ç¹ã«æ¥ç¶ãã蟺ã®éžã³æ¹)| = |V| - |æå€§ãããã³ã°|
- |æå°ç¹ã«ããŒ(ãã¹ãŠã®èŸºã«æ¥ç¶ããé ç¹ã®éžã³æ¹)| = |æå€§ãããã³ã°|
- |æå€§å®å®éå| = |V| - |æå€§ãããã³ã°|
- æš â LCAããªã€ã©ãŒãã¢ãŒ (é å or äºæ¬¡å ãããã)ããããªã³ã°ãHLåè§£ (åè)
- DAG â ããããžã«ã«ãœãŒãã匷é£çµæååè§£ããã«ãã³ãã©ãŒãã§æé·çµè·¯
- 確çãæåŸ
å€
- DP
- ç·åœ¢æ§ (éã¿*確ç ⊠å®çŸ©ã«åã£ãŠæã§èšç®ããŠã¿ãããšïŒïŒ
- 挞ååŒãé£ç«äžæ¬¡æ¹çšåŒã«ãã (ã©ã³ãã ãŠã©ãŒã¯ã®ããã«)
- nCmãnPmãn!ã䜿ã£ãŠèšç®ããªããŠãè§£ãã or 䜿ããªãã»ããç°¡åãªåé¡ã®ã»ããå€ã
- ç¶æ é·ç§»å³ãæžãã¹ã
- æŽæ°è«
- çŽ å æ°åè§£(åæ°ãšãçŽæ°ãšãã£ãèšèã«æ³šç®)ãGCDãLCMã埪ç°
- ãnãmã§å²ãåãããã¯
n=km
ãŸãã¯n/m=k
ïŒãnãmã§å²ã£ãäœããaãã¯n=km+a
ãªã©ãšãã
- 1-indexed, 0-indexed, (i, j) <-> (x, y) or (y, x)
- éåºé, éåºé
- INFã倧ãããã or å°ãããã
- ã°ã©ã
- å€é蟺ãèªå·±ã«ãŒããéé£çµ
- 誀差
- -0.000
- 1.0/n <=> 1.0/m â 1.0*m <=> 1.0*n ã«å€åœ¢
- 幟äœ
- ç·åã¯ç«¯ãå«ããïŒ
- 䞊è¡, åäžã®çŽç·
- ãå³åœ¢ãã1ç¹ãŸãã¯2ç¹ã§æ§æãããŠããæã«ç¹å¥ãªåŠçãå¿ èŠ