由於loceaner太菜了,他什麼東西都不會
因此他打算學一個東西就記錄一下
不過由於他很菜,因此他不會寫原理……
並且,他但願在2019CSP以前不會斷更
就醬紫,就是寫給他本身的……由於他太菜了node
\[\sum_{i = 0}^{x}C(x, i)* C(y, i) = C(x + y, x)\]ios
如何使用負數下標呢?
讓數組前面有東西c++
int y[100]; int *z = y + 50;
這樣的話調用\(z[-50]\)就變成了調用\(y[0]\)git
z[-50] = y[0];
而後這樣就能夠實現調用啦~算法
其實還有一個更暴力的方法:用\(map\)數組
\(map\)是\(\log n\)的\(map\)
\(unordered\_map\)是\(O(1)\)的\(map\)(到\(c++11\)纔會有)數據結構
//知識點:二維前綴和 /* By:Loceaner */ #include <cstdio> #include <cstring> #include <iostream> using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); return x * f; } const int N = 1000; int n, m; int a[N][N], b[N][N]; int main() { n = read(), m = read(); for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { a[i][j] = read(); b[i][j] = a[i][j] + b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1]; } } for(int i, u1, v1, u2, v2; i <= m; i++) { u1 = read(), v1 = read(), u2 = read(), v2 = read(); cout << b[u2][v2] - b[u1 - 1][v2] - b[u2][v1 - 1] + b[u1 - 1][v1 - 1] << '\n'; } return 0; }
//知識點: /* By:Loceaner */ #include <cstdio> #include <cstring> #include <iostream> using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); return x * f; } const int N = 1e3 + 11; int n, m, a[N][N]; int main() { n = read(), m = read(); for(int i = 1, u1, u2, v1, v2; i <= m; i++) { u1 = read(), v1 = read(), u2 = read(), v2 = read(); a[u1][v1] += 1; a[u2 + 1][v2 + 1] += 1; a[u2 + 1][v1] -= 1; a[u1][v2 + 1] -= 1; } //C[x1][y1] += x , C[x2 + 1][y2 + 1] += x , C[x1][y2 + 1] -= x , C[x2 + 1][y1] -= x; for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { a[i][j] = a[i][j] + a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];; } } for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { cout << a[i][j] << ' '; } cout << '\n'; } return 0; }
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int A = 1e5 + 11; const int B = 1e6 + 11; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); return x * f; } int n, m, a[A], b[A]; void solve(int l, int r) { if(l == r) return; int mid = (l + r) >> 1; solve(l, mid), solve(mid + 1, r); int i = l, j = mid + 1, k = l; while(i <= mid && j <= r) { if(a[i] <= a[j]) b[k++] = a[i++]; else b[k++] = a[j++]; } while(i <= mid) b[k++] = a[i++]; while(j <= r) b[k++] = a[j++]; for(int i = l; i <= r; i++) a[i] = b[i]; } int main() { // freopen("a.in", "r", stdin); n = read(); for(int i = 1; i <= n; i++) a[i] = read(); solve(1, n); for(int i = 1; i <= n; i++) cout << a[i] << ' '; return 0; }
給定3組數\(a, b, c\)
\(a[1]\)~\(a[n]\),\(b[1]\)~\(b[n]\),\(c[1]\)~\(c[n]\)
其中\(c[1]\)~\(c[n]\)是\(b[1]\)~\(b[n]\)的亂序排列
\(a[1]*b[n]+a[2]*b[n-1]+...<=a[1]*c[1]+a[2]*c[2]+...<=a[1]*b[1]+a[2]*b[2]+...\)
即:逆序和 <= 亂序和 <= 正序和ui
在平常的題目中,必定要看好數據範圍,若是會爆\(int\)的話,不要忘記開\(long long\)(無數次被坑!!)this
最讓人煩的就是高精度了,某些題並不難,可是要寫高精。。煩\(\color{white}{(ps:板子來自lfd)}\)spa
namespace BigInteger { struct Big_integer { int d[10005], len; void clean() {while(len > 1 and !d[len - 1]) len--;} Big_integer() {memset(d, 0, sizeof d);len = 1;} Big_integer(int num) {*this = num;} Big_integer operator = (const char* num) { memset(d, 0, sizeof d); len = strlen(num); for (int i = 0; i < len; i++) d[i] = num[len - 1 - i] - '0'; clean(); return *this; } Big_integer operator = (int num) { char s[10005]; sprintf(s, "%d", num); *this = s; return *this; } Big_integer operator * (const Big_integer &b) const { int i, j; Big_integer c; c.len = len + b.len; for (j = 0; j < b.len; j++) for (i = 0; i < len; i++) c.d[i + j] += d[i] * b.d[j]; for (i = 0; i < c.len - 1; i++) c.d[i + 1] += c.d[i] / 10, c.d[i] %= 10; c.clean(); return c; } Big_integer operator / (const int &b) { int i, j, a = 0; Big_integer c = *this; for (i = len - 1; i >= 0; i--) { a = a * 10 + d[i]; for (j = 0; j < 10; j++) if (a < b * (j + 1)) break; c.d[i] = j; a = a - b * j; } c.clean(); return c; } bool operator < (const Big_integer &b) const { if (len != b.len) return len < b.len; for (int i = len - 1; i >= 0; i--) if (d[i] != b.d[i]) return d[i] < b.d[i]; return false; } string str() const { char s[10005]; for (int i = 0; i < len; i++) s[len - 1 - i] = d[i] + '0'; return s; } }; istream& operator >> (istream& in, Big_integer &x) { string s; in >> s; x = s.c_str(); return in; } ostream& operator << (ostream& out, const Big_integer &x) { out << x.str(); return out; } } using namespace BigInteger;
for(int i = 0; i < T.size(); i++){ while(! stk.empty() && stk.top() > T[i]){ stk.pop(); } stk.push(A[i]); }
上經典的滑動窗口問題
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #define maxn 1000100 using namespace std; int q[maxn], a[maxn]; int n, k; void getmin() { int head = 0, tail = 0; for (int i = 1; i < k; i++) { while (head <= tail && a[q[tail]] >= a[i]) tail--; q[++tail] = i; } for (int i = k; i <= n; i++) { while (head <= tail && a[q[tail]] >= a[i]) tail--; q[++tail] = i; while (q[head] <= i - k) head++; printf("%d ", a[q[head]]); } } void getmax() { int head = 0, tail = 0; for (int i = 1; i < k; i++) { while (head <= tail && a[q[tail]] <= a[i]) tail--; q[++tail] = i; } for (int i = k; i <= n; i++) { while (head <= tail && a[q[tail]] <= a[i]) tail--; q[++tail] = i; while (q[head] <= i - k) head++; printf("%d ", a[q[head]]); } } int main() { scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); getmin(); printf("\n"); getmax(); printf("\n"); return 0; }
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int A = 1e6 + 11; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); return x * f; } int n, m, root, mod, w[A], pre[A]; struct node { int to, nxt; } e[A]; int head[A], cnt; inline void add_edge(int from, int to) { e[++cnt].to = to; e[cnt].nxt = head[from]; head[from] = cnt; } namespace Seg { struct tree { int l, r, w, lazy; } t[A]; #define lson rt << 1 #define rson rt << 1 | 1 inline void pushup(int rt) { t[rt].w = (t[lson].w + t[rson].w) % mod; } inline void pushdown(int rt) { t[lson].lazy += t[rt].lazy, t[rson].lazy += t[rt].lazy; t[lson].lazy %= mod, t[rson].lazy %= mod; t[lson].w += (t[lson].r - t[lson].l + 1) * t[rt].lazy; t[lson].w %= mod; t[rson].w += (t[rson].r - t[rson].l + 1) * t[rt].lazy; t[lson].w %= mod; t[rt].lazy = 0; } void build(int rt, int l, int r) { t[rt].l = l, t[rt].r = r; if(l == r) { t[rt].w = w[pre[l]] % mod; return; } int mid = (l + r) >> 1; build(lson, l, mid); build(rson, mid + 1, r); pushup(rt); return; } void add(int rt, int l, int r, int val) { if(l <= t[rt].l && t[rt].r <= r) { t[rt].lazy = (t[rt].lazy + val) % mod; t[rt].w = (t[rt].w + (t[rt].r - t[rt].l + 1) * val) % mod; return; } if(t[rt].lazy) pushdown(rt); int mid = (t[rt].l + t[rt].r) >> 1; if(l <= mid) add(lson, l, r, val); if(r > mid) add(rson, l, r, val); pushup(rt); } int asksum(int rt, int l, int r) { if(l <= t[rt].l && t[rt].r <= r) { return t[rt].w % mod; } if(t[rt].lazy) pushdown(rt); int mid = (t[rt].l + t[rt].r) >> 1, ans = 0; if(l <= mid) ans += asksum(lson, l, r); if(r > mid) ans += asksum(rson, l, r); return ans; } } int dfn[A], son[A], siz[A], dep[A], fa[A], top[A], tot; void dfs1(int now, int fr) { siz[now] = 1, fa[now] = fr, dep[now] = dep[fr] + 1; for(int i = head[now]; i; i = e[i].nxt) { int to = e[i].to; if(to == fr) continue; dfs1(to, now); siz[now] += siz[to]; if(siz[to] > siz[son[now]]) son[now] = to; } } void dfs2(int now, int tp) { dfn[now] = ++tot, pre[tot] = now, top[now] = tp; if(son[now]) dfs2(son[now], tp); for(int i = head[now]; i; i = e[i].nxt) { int to = e[i].to; if(to == fa[now] || to == son[now]) continue; dfs2(to, to); } } inline void add_qwq(int x, int y, int val) { while(top[x] != top[y]) { if(dep[top[x]] < dep[top[y]]) swap(x, y); Seg::add(1, dfn[top[x]], dfn[x], val); x = fa[top[x]]; } if(dep[x] > dep[y]) swap(x, y); Seg::add(1, dfn[x], dfn[y], val); return; } inline int asksum_qwq(int x, int y) { int ans = 0; while(top[x] != top[y]) { if(dep[top[x]] < dep[top[y]]) swap(x, y); ans += Seg::asksum(1, dfn[top[x]], dfn[x]); ans %= mod; x = fa[top[x]]; } if(dep[x] > dep[y]) swap(x, y); ans += Seg::asksum(1, dfn[x], dfn[y]); ans %= mod; return ans % mod; } int main() { n = read(), m = read(), root = read(), mod = read(); for(int i = 1; i <= n; i++) w[i] = read() % mod; for(int i = 1; i < n; i++) { int x = read(), y = read(); add_edge(x, y), add_edge(y, x); } dfs1(root, 0); dfs2(root, root); Seg::build(1, 1, n); while(m--) { int opt = read(), x, y, z; if(opt == 1) x = read(), y = read(), z = read() % mod, add_qwq(x, y, z); if(opt == 2) x = read(), y = read(), cout << asksum_qwq(x, y) % mod << '\n'; if(opt == 3) x = read(), z = read(), Seg::add(1, dfn[x], dfn[x] + siz[x] - 1, z); if(opt == 4) x = read(), cout << Seg::asksum(1, dfn[x], dfn[x] + siz[x] - 1) % mod << '\n'; } return 0; }
/* By:Loceaner */ #include <cstdio> #include <cstring> #include <iostream> #define ull unsigned long long using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); return x * f; } const int N = 211; char pa[N][N], meng[N]; int n, m, a[N], l[N], ans, cnt[N]; ull p[N], cnm[N][N], sjp[N]; bool query(int l1, int r1,int now) { ull h1, h2; h1 = sjp[r1] - sjp[l1 - 1] * p[r1 - l1 + 1]; h2 = cnm[now][l[now]]; return h1 == h2; } void work2() {//cnm memset(sjp, 0, sizeof(sjp)); int len = strlen(meng + 1); for(int i = 1; i <= len; i++) { sjp[i] = sjp[i - 1] * 27 + meng[i] - 'a' + 1; } for(int i = 1; i <= m; i++) { for(int j = 1; j <= len; j++) { if(meng[j] == pa[i][1]) { if(query(j, j + l[i] - 1, i)) ans += j * a[i]; } } } } int main() { freopen("dream.in", "r", stdin); freopen("dream.out", "w", stdout); n = read(), m = read(); p[0] = 1; for(int i = 1; i <= 200; i++) p[i] = p[i - 1] * 27ull; for(int i = 1; i <= m; i++) scanf("%s", pa[i] + 1), l[i] = strlen(pa[i] + 1); for(int i = 1; i <= m; i++) for(int j = 1; j <= l[i]; j++) cnm[i][j] = cnm[i][j - 1] * 27 + pa[i][j] - 'a' + 1; for(int i = 1; i <= m; i++) a[i] = read(); for(int i = 1; i <= n; i++) scanf("%s", meng + 1), work2(); cout << ans << '\n'; return 0; }
//知識點:快速乘 /* By:Loceaner */ #include <cstdio> #include <cstring> #include <iostream> #define int long long using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); return x * f; } int a, b, p, ans; int mul(int a, int b, int mod) { int res = 0; while(b) { if(b & 1) res = (res + a) % mod; a = (a + a) % mod; b >>= 1; } return res % mod; } signed main() { a = read(), b = read(), p = read(); ans = mul(a, b, p); cout << ans << '\n'; return 0; }
//知識點:快速冪 /* By:Loceaner */ #include <cstdio> #include <cstring> #include <iostream> #define int long long using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); return x * f; } int a, b, p, ans; int power(int a, int b, int mod) { int res = 1; while(b) { if(b & 1) res = res * a % mod; a = a * a % mod; b >>= 1; } return res % mod; } signed main() { a = read(), b = read(), p = read(); ans = power(a, b, p); cout << ans << '\n'; return 0; }
void prime(int n) { cnt = 0; vis[0] = vis[1] = 1; for(int i = 2; i <= n; ++i) { if(!vis[i]) { p[++cnt] = i; for(int j = i * i; j <= n; j+=i) { vis[j] = true; } } } }
int vis[N], p[N], cnt; void prepare() { vis[0] = vis[1] = 1; for(int i = 2; i <= n; i++) { if(!vis[i]) p[++cnt] = i; for(int j = 1; j <= cnt; j++) { if(i * p[j] > n) break; vis[i * p[j]] = 1; if(i % p[j] == 0) break; } } }
普通二分
//知識點: /* By:Loceaner */ #include <cstdio> #include <cstring> #include <iostream> using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); return x * f; } const int N = 10001; int f[N], a[N], n; int len = 1; int main() { memset(f, 0x3f, sizeof(f)); n = read(); for(int i = 1; i <= n; i++) a[i] = read(); f[len] = a[1]; for(int i = 2; i <= n; i++) { int l = 1, r = len, mid, rec; if(a[i] > f[len]) f[++len] = a[i]; else { while(l <= r) { mid = (l + r) / 2; if(f[mid] >= a[i]) rec = mid, r = mid - 1; else l = mid + 1; } f[rec] = min(f[rec], a[i]); } } for(int i = 1; i <= len; i++) cout << f[i] << " "; cout << '\n' << len << '\n'; return 0; } /* 9 7 2 1 5 6 4 3 8 9 */
lower_bound
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); return x * f; } const int N = 10001; int f[N], a[N], n; int len = 1; int main() { memset(f, 0x3f, sizeof(f)); n = read(); for(int i = 1; i <= n; i++) a[i] = read(); f[1] = a[1]; for(int i = 2; i <= n; i++) { if(a[i] > f[len]) f[++len] = a[i]; else { int p = lower_bound(f + 1, f + len + 1 , a[i]) - f; f[p] = a[i]; } } for(int i = 1; i <= len; i++) cout << f[i] << " "; cout << '\n' << len << '\n'; return 0; }
\(n^2\)
#include <cstdio> #include <cstring> #include <iostream> using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48); return x * f; } const int N = 1011; int dp[N][N], a1[N], a2[N], n, m; int main() { n = read(); for(int i = 1; i <= n; i++) a1[i] = read(); for(int i = 1; i <= n; i++) a2[i] = read(); for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) { dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); if(a1[i] == a2[j]) dp[i][j] = max(dp[i][j], dp[i - 1][j - 1] + 1); } cout << dp[n][n] << '\n'; return 0; }
#include <bits/stdc++.h> using namespace std; inline int read() { char c = getchar(); int x = 0, f = 1; for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1; for( ; isdigit(c); c = getchar()) x = x * 10 + c - 48; return x * f; } const int N = 1011; struct node { int to, nxt; } e[N]; int low[N], dfn[N], tot, topp = 0, sta[N], cnt, head[N]; bool vis[N]; inline void add(int from, int to) { e[++tot].to = to; e[tot].nxt = head[from]; head[from] = tot; } void tarjan(int u) { dfn[u] = low[u] = ++cnt, sta[++topp] = u, vis[u] = 1; for(int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if(!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]); else if(vis[v]) low[u] = min(low[u], dfn[v]); } if(dfn[u] == low[u]) { do { cout << sta[topp] << ' '; vis[sta[topp--]] = 0; }while(u != sta[topp + 1]); cout << '\n'; } } int n, m; int main() { n = read(), m = read(); for(int i = 1; i <= m; i++) { int u = read(), v = read(); add(u, v); } for(int i = 1; i <= n; i++) if(!dfn[i]) tarjan(i); } /* 5 8 1 2 2 3 3 6 5 6 1 4 4 5 5 1 2 5 */