@jason-fan
        
        2023-07-30T13:51:11.000000Z
        字数 112222
        阅读 137
    jasonfan 的算法模板。
/*Dancing Links X : 舞蹈链优化 X 算法干啥的 --> 求解精准覆盖问题Oi-wiki(Dancing Links) --> https://oi-wiki.org/search/dlx/*/#include <bits/stdc++.h>using namespace std;const int N = 505;int n, m, a[N][N];namespace DLX { // 舞蹈链,这实际上是个双十字循环链表const int N = 10010;int tot, fir[N], siz[N];int L[N], R[N], U[N], D[N];int col[N], row[N], st[N], ans;void Remove(int c) {L[R[c]] = L[c], R[L[c]] = R[c];for (int i = D[c]; i != c; i = D[i]) for (int j = R[i]; j != i;j = R[j]) U[D[j]] = U[j], D[U[j]] = D[j], --siz[col[j]];}void Recover(int c) {for (int i = U[c]; i != c; i = U[i]) for (int j = L[i]; j != i;j = L[j]) U[D[j]] = D[U[j]] = j, ++siz[col[j]];L[R[c]] = R[L[c]] = c;}void Insert(int r, int c) {++tot; row[tot] = r; col[tot] = c; ++siz[c];U[tot] = c; D[tot] = D[c]; U[D[c]] = tot; D[c] = tot;if (!fir[r])fir[r] = L[tot] = R[tot] = tot;else {L[tot] = fir[r]; R[tot] = R[fir[r]];L[R[fir[r]]] = tot; R[fir[r]] = tot;}}void Build(int r, int c) {for (int i = 0; i <= c; ++i) L[i] = i - 1, R[i] = i + 1, U[i] = D[i] = i;L[0] = c, R[c] = 0; tot = c;memset(fir, 0, sizeof(fir));memset(siz, 0, sizeof(siz));}bool Dance(int dep) {int c = R[0];if (!R[0]) { ans = dep; return 1;}for (int i = R[0]; i != 0; i = R[i]) if (siz[i] < siz[c]) c = i;Remove(c);for (int i = D[c]; i != c; i = D[i]) {st[dep] = row[i];for (int j = R[i]; j != i; j = R[j]) Remove(col[j]);if (Dance(dep + 1)) return 1;for (int j = L[i]; j != i; j = L[j]) Recover(col[j]);}Recover(c);return 0;}}void solve() {using namespace DLX;Build(n, m);for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) if (a[i][j] == 1) Insert(i, j);bool fg = Dance(1);if (!fg) puts("No Solution!");else {for (int i = 1; i < ans; ++i) printf("%d ", st[i]);printf("\n");}}int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) scanf("%d", &a[i][j]);solve();}
// 树状数组(Fenwick Tree) 区间加减,区间求和#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N = 1000010;struct fenwick {ll s1[N], s2[N]; int n;void _add(int p, int v) {for (int x = p; x <= n; x += x & -x) s1[x] += v, s2[x] += (ll)v * p;}ll ask(int p) {ll r = 0; for (int x = p; x > 0; x -= x & -x) r += (ll)(p + 1) * s1[x] - s2[x]; return r;}ll query(int l, int r) {return ask(r) - ask(l - 1);}void modify(int l, int r, int v) {_add(l, v); _add(r + 1, -v);}void init(int n, int a[]) {fenwick::n = n;for (int i = 1, j; i <= n; ++i) {s1[i] += a[i] - a[i - 1]; s2[i] += (ll)(a[i] - a[i - 1]) * i;j = i + (i & -i);if (j <= n) s1[j] += s1[i], s2[j] += s2[i];}}} T;int n, q, a[N];int main() {scanf("%d%d", &n, &q);for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);T.init(n, a);while (q--) {int op, l, r, x;scanf("%d%d%d", &op, &l, &r);if (op == 1) {scanf("%d", &x);T.modify(l, r, x);} elseprintf("%lld\n", T.query(l, r));}return 0;}
// fhq - treap 简易模板#include <bits/stdc++.h>#define ls(p) t[p].l#define rs(p) t[p].r#define mid ((l+r)>>1)using namespace std;const int N = 100010;mt19937 rd(random_device{}()); // random makerstruct node {int l, r, siz, rnd, val, tag; /* other data/tags */} t[N]; int tot, root;/* ---------- for recycle nodes ------------int cyc[N],cyccnt;inline void delnode(int p) {cyc[++cyccnt]=p;}inline void newnode(int val) {int id=(cyccnt>0)?cyc[cyccnt--]:++tot;t[id]={0,0,1,(int)(rd()),val}; return id;}*/inline int newnode(int val) { t[++tot] = {0, 0, 1, (int)(rd()), val}; return tot;} // create a new nodeinline void updata(int p) {t[p].siz = t[ls(p)].siz + t[rs(p)].siz + 1; /* pushup other datas */ }inline void pushtag(int p, int vl) { /* tag to push */ }inline void pushdown(int p) {if (t[p].tag != std_tag) {if (ls(p)) pushtag(ls(p), t[p].tag);if (rs(p)) pushtag(rs(p), t[p].tag);t[p].tag = std_tag;}}int merge(int p, int q) {if (!p || !q) return p + q;if (t[p].rnd < t[q].rnd) {pushdown(p);rs(p) = merge(rs(p), q);updata(p); return p;} else {pushdown(q);ls(q) = merge(p, ls(q));updata(q); return q;}}void split(int p, int k, int &x, int &y) {if (!p) x = 0, y = 0;else {pushdown(p);if (t[ls(p)].siz >= k) y = p, split(ls(p), k, x, ls(p));else x = p, split(rs(p), k - t[ls(p)].siz - 1, rs(p), y);updata(p);}}int build(int l, int r) { // build tree on a[l..r], return the rootif (l > r) return 0;return merge(build(l, mid - 1), merge(newnode(a[mid]), build(mid + 1, r)));}/*other functions base on split() and merge()*/int main() {}
#include <bits/stdc++.h>using namespace std;template<typename DataType, int N = 100010>struct fhq_Treap {private:const DataType inf; //inf的定义struct node {DataType key; int rnd;int siz, l, r;} d[N];int rt = 0, tot;void updata(int t) {d[t].siz = d[d[t].l].siz + d[d[t].r].siz + 1;}pair<int, int> split(int t, int p) {pair<int, int> res(0, 0);if (t == 0) return res;if (p <= d[d[t].l].siz) {res = split(d[t].l, p);d[t].l = res.second;updata(t);res.second = t;} else {res = split(d[t].r, p - 1 - d[d[t].l].siz);d[t].r = res.first;updata(t);res.first = t;}return res;}int merge(int a, int b) {if (a == 0) return b;if (b == 0) return a;if (d[a].rnd < d[b].rnd) {d[a].r = merge(d[a].r, b);updata(a);return a;}d[b].l = merge(a, d[b].l);updata(b);return b;}int x_rank(int t, DataType key) {if (t == 0) return 1;if (!(d[t].key < key)) return x_rank(d[t].l, key); //key<=d[t].keyreturn d[d[t].l].siz + 1 + x_rank(d[t].r, key);}DataType getkey(int t, int rk) {if (rk <= d[d[t].l].siz) return getkey(d[t].l, rk);if (rk == d[d[t].l].siz + 1) return d[t].key;return getkey(d[t].r, rk - d[d[t].l].siz - 1);}int pre(int t, DataType key, int res = 0) {if (t == 0) return res;if (d[t].key < key) return pre(d[t].r, key, t);return pre(d[t].l, key, res);}int nxt(int t, DataType key, int res = 0) {if (t == 0) return res;if (key < d[t].key) return nxt(d[t].l, key, t);return nxt(d[t].r, key, res);}int newnode(DataType key) {d[++tot] = {key, rand(), 1, 0, 0};return tot;}public:void build() {rt = tot = 0;srand(time(0));rt = newnode(inf); //这里需要修改d[rt].l = newnode(-inf);updata(rt);}void insert(DataType key) {int k = x_rank(rt, key);pair<int, int> a = split(rt, k - 1);rt = merge(merge(a.first, newnode(key)), a.second);}void remove(DataType key) {int k = x_rank(rt, key);pair<int, int> a = split(rt, k - 1), b = split(a.second, 1);rt = merge(a.first, b.second);}int getrank(DataType key) {return x_rank(rt, key);}DataType getpre(DataType key) {return d[pre(rt, key)].key;}DataType getnxt(DataType key) {return d[nxt(rt, key)].key;}DataType getkey(int rk) {return getkey(rt, rk);}int getroot() {return rt;}};
#include <cstring>typedef long long ll;namespace hashtable1 {const int M = 19260817;const int MAX_SIZE = 2000000;struct Hash_map {struct data {int nxt;ll key, value; // (key,value)} e[MAX_SIZE];int head[M], size;inline int f(ll key) { return key % M; } // 哈希函数ll &operator[](const ll &key) { // 重载[]int ky = f(key);for (int i = head[ky]; i != -1; i = e[i].nxt)if (e[i].key == key) return e[i].value;return e[++size] = data{head[ky], key, 0}, head[ky] = size, e[size].value;}void clear() { // 清空memset(head, -1, sizeof(head));size = 0;}Hash_map() {clear();} // 初始化清空};}namespace hashtable2 {const int M = 19260817;const int MAX_SIZE = 2000000;struct Hash {struct data {int nxt;ll key, value;} e[MAX_SIZE];int head[M], size;inline int f(ll key) { return key % M; } // 哈希函数void clear() { // 清空memset(head, -1, sizeof(head));size = 0;}ll query(ll key) { // 查询for (int i = head[f(key)]; i != -1; i = e[i].nxt)if (e[i].key == key) return e[i].value;return -1;}ll modify(ll key, ll value) { // 修改for (int i = head[f(key)]; i != -1; i = e[i].nxt)if (e[i].key == key) return e[i].value = value;return -1;}ll insert(ll key, ll value) { // 插入if (query(key) != -1) return -1;e[++size] = data{head[f(key)], key, value};head[f(key)] = size;return value;}};}
/*luogu P4357 [CQOI2016]K 远点对K-D Tree 二维平面邻域查询题意:平面上 N (1e5) 个点,求第 K (1e2) 远点对距离*/#include <bits/stdc++.h>template <typename T>inline void red(T &x) {x = 0; bool f = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') f ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (T)(ch ^ 48), ch = getchar();if (f) x = -x;}using namespace std;typedef double db;typedef long long ll;const int N = 100010;int n, k;priority_queue<ll, vector<ll>, greater<ll> >q;template <typename _Tp> inline void umin(_Tp &x, _Tp y) {(x > y) &&(x = y);}template <typename _Tp> inline void umax(_Tp &x, _Tp y) {(x < y) &&(x = y);}namespace KDTree {struct node {int X[2];int &operator[](const int k) {return X[k];}} p[N];int nowd;bool cmp(node a, node b) {return a.X[nowd] < b.X[nowd];}int lc[N], rc[N], L[N][2], R[N][2]; // lc/rc 左右孩子;L/R 对应超矩形各个维度范围inline ll sqr(int x) {return 1ll * x * x;}void pushup(int x) { // 更新该点所代表空间范围L[x][0] = R[x][0] = p[x][0];L[x][1] = R[x][1] = p[x][1];if (lc[x]) {umin(L[x][0], L[lc[x]][0]); umax(R[x][0], R[lc[x]][0]);umin(L[x][1], L[lc[x]][1]); umax(R[x][1], R[lc[x]][1]);}if (rc[x]) {umin(L[x][0], L[rc[x]][0]); umax(R[x][0], R[rc[x]][0]);umin(L[x][1], L[rc[x]][1]); umax(R[x][1], R[rc[x]][1]);}}int build(int l, int r) {if (l > r) return 0;int mid = (l + r) >> 1;// >>> 方差建树db av[2] = {0, 0}, va[2] = {0, 0}; // av 平均数,va 方差for (int i = l; i <= r; ++i) av[0] += p[i][0], av[1] += p[i][1];av[0] /= (r - l + 1); av[1] /= (r - l + 1);for (int i = l; i <= r; ++i) {va[0] += sqr(av[0] - p[i][0]);va[1] += sqr(av[1] - p[i][1]);}if (va[0] > va[1]) nowd = 0;else nowd = 1; // 找方差大的维度划分// >>> 轮换建树 nowd=dep%Dnth_element(p + l, p + mid, p + r + 1, cmp); // 以该维度中位数分割lc[mid] = build(l, mid - 1); rc[mid] = build(mid + 1, r);pushup(mid);return mid;}ll dist(int a, int x) { // 估价函数,点 a 到树上 x 点对应空间最远距离return max(sqr(p[a][0] - L[x][0]), sqr(p[a][0] - R[x][0])) +max(sqr(p[a][1] - L[x][1]), sqr(p[a][1] - R[x][1]));}void query(int l, int r, int a) { // 点 a 邻域查询if (l > r) return ;int mid = (l + r) >> 1;ll t = sqr(p[mid][0] - p[a][0]) + sqr(p[mid][1] - p[a][1]);if (t > q.top()) q.pop(), q.push(t); // 更新答案ll disl = dist(a, lc[mid]), disr = dist(a, rc[mid]);if (disl > q.top() && disr > q.top()) // 两边都有机会更新,优先搜大的(disl > disr) ? (query(l, mid - 1, a), query(mid + 1, r, a)) : (query(mid + 1, r, a), query(l, mid - 1, a));else(disl > q.top()) ? query(l, mid - 1, a) : query(mid + 1, r, a);}}using namespace KDTree;int main() {red(n); red(k); k *= 2;for (int i = 1; i <= k; ++i) q.push(0);for (int i = 1; i <= n; ++i) red(p[i][0]), red(p[i][1]);build(1, n);for (int i = 1; i <= n; ++i) query(1, n, i);printf("%lld\n", q.top());}
/*K-D Tree 维护空间权值 (单点修改 & 空间查询)时间复杂度 O(log n) ~ O(n^(1-1/k))*/#include <bits/stdc++.h>template <typename T>inline void red(T &x) {x = 0; bool f = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') f ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (T)(ch ^ 48), ch = getchar();if (f) x = -x;}using namespace std;const int N = 200010;typedef double db;template <typename _Tp> void umin(_Tp &x, _Tp y) {if (x > y) x = y;}template <typename _Tp> void umax(_Tp &x, _Tp y) {if (x < y) x = y;}template <typename _Tp> _Tp sqr(_Tp x) {return x * x;}namespace KDT {struct dat {int X[2];int &operator[](const int k) {return X[k];}} p[N];db alp = 0.725; // 重构常数int nowd;bool cmp(int a, int b) {return p[a][nowd] < p[b][nowd];}int root, cur, d[N], lc[N], rc[N], L[N][2], R[N][2], siz[N], sum[N], val[N];// root:根 cur:总点数 d:当前分割维度 lc/rc:左右儿子 L/R:当前空间范围 siz:子树大小 sum/val 空间的值,单点的值int g[N], t; // 用于重构的临时数组void pushup(int x) {siz[x] = siz[lc[x]] + siz[rc[x]] + 1;sum[x] = sum[lc[x]] + sum[rc[x]] + val[x];L[x][0] = R[x][0] = p[x][0];L[x][1] = R[x][1] = p[x][1];if (lc[x]) {umin(L[x][0], L[lc[x]][0]); umax(R[x][0], R[lc[x]][0]);umin(L[x][1], L[lc[x]][1]); umax(R[x][1], R[lc[x]][1]);}if (rc[x]) {umin(L[x][0], L[rc[x]][0]); umax(R[x][0], R[rc[x]][0]);umin(L[x][1], L[rc[x]][1]); umax(R[x][1], R[rc[x]][1]);}}int build(int l, int r) { // 对 g[1...t] 进行建树 ,!!注意了,对应点都是 g[x]if (l > r) return 0;int mid = (l + r) >> 1;db av[2] = {0, 0}, va[2] = {0, 0};for (int i = l; i <= r; ++i) av[0] += p[g[i]][0], av[1] += p[g[i]][1];av[0] /= (r - l + 1); av[1] /= (r - l + 1);for (int i = l; i <= r; ++i) va[0] += sqr(av[0] - p[g[i]][0]), va[1] += sqr(av[1] - p[g[i]][1]);if (va[0] > va[1]) d[g[mid]] = nowd = 0;else d[g[mid]] = nowd = 1;nth_element(g + l, g + mid, g + r + 1, cmp);lc[g[mid]] = build(l, mid - 1); rc[g[mid]] = build(mid + 1, r);pushup(g[mid]);return g[mid];}void expand(int x) { // 将子树展开到临时数组里if (!x) return;expand(lc[x]);g[++t] = x;expand(rc[x]);}void rebuild(int &x) { // x 所在子树重构t = 0; expand(x);x = build(1, t);}bool chk(int x) {return alp * siz[x] <= (db)max(siz[lc[x]], siz[rc[x]]);} // 判断失衡void insert(int &x, int a) { // 插入点 a , p[a],val[a] 为其信息if (!x) { x = a; pushup(x); d[x] = rand() & 1; return; }if (p[a][d[x]] <= p[x][d[x]]) insert(lc[x], a);else insert(rc[x], a);pushup(x);if (chk(x)) rebuild(x); // 失衡暴力重构}dat Lt, Rt; // 询问一块空间的值(为了减小常数把参数放在外面)int query(int x) {if (!x || Rt[0] < L[x][0] || Lt[0] > R[x][0] || Rt[1] < L[x][1]|| Lt[1] > R[x][1]) return 0; // 结点为空或与询问取间无交if (Lt[0] <= L[x][0] && R[x][0] <= Rt[0] && Lt[1] <= L[x][1]&& R[x][1] <= Rt[1]) return sum[x]; // 区间完全覆盖int ret = 0;if (Lt[0] <= p[x][0] && p[x][0] <= Rt[0] && Lt[1] <= p[x][1]&& p[x][1] <= Rt[1]) ret += val[x]; // 当前点在区间内return query(lc[x]) + query(rc[x]) + ret;}}using namespace KDT;int n, lstans;int main() {red(n);for (int op;;) {red(op);switch (op) {case 1:++cur; red(p[cur][0]); red(p[cur][1]); red(val[cur]);p[cur][0] ^= lstans; p[cur][1] ^= lstans; val[cur] ^= lstans;insert(root, cur);break;case 2:red(Lt[0]); red(Lt[1]); red(Rt[0]); red(Rt[1]);Lt[0] ^= lstans; Lt[1] ^= lstans; Rt[0] ^= lstans; Rt[1] ^= lstans;printf("%d\n", lstans = query(root));break;case 3: return 0; break;}}return 0;}
// Link Cut Tree#include <cstdio>template <typename T>inline void red(T &x) {x = 0; bool f = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') f ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (T)(ch ^ 48), ch = getchar();if (f) x = -x;}template <typename _Tp> void swap(_Tp &x, _Tp &y) {_Tp tmp = x; x = y; y = tmp;}const int N = 100010;namespace LCT {int ch[N][2], f[N], sum[N], val[N], tag[N], dat[N]; // dat 维护的链信息, val 点上信息inline void PushUp(int x) {dat[x] = dat[ch[x][0]] ^ dat[ch[x][1]] ^ val[x];}inline void PushRev(int x) {swap(ch[x][0], ch[x][1]); tag[x] ^= 1;}inline void PushDown(int x) {if (tag[x] == 0) return ;PushRev(ch[x][0]); PushRev(ch[x][1]); tag[x] = 0;}inline bool Get(int x) {return ch[f[x]][1] == x;} // 是父亲的哪个儿子inline bool IsRoot(int x) {return (ch[f[x]][1] != x && ch[f[x]][0] != x);} // 是否是当前 Splay 的根inline void Rotate(int x) { // Splay 旋转int y = f[x], z = f[y], k = Get(x);if (!IsRoot(y)) ch[z][Get(y)] = x;ch[y][k] = ch[x][k ^ 1]; f[ch[x][k ^ 1]] = y;ch[x][k ^ 1] = y; f[y] = x; f[x] = z;PushUp(y); PushUp(x);}void Updata(int x) { // Splay 中从上到下 PushDownif (!IsRoot(x)) Updata(f[x]);PushDown(x);}inline void Splay(int x) { // Splay 上把 x 转到根Updata(x);for (int fa; fa = f[x], !IsRoot(x); Rotate(x)) {if (!IsRoot(fa)) Rotate(Get(fa) == Get(x) ? fa : x);}PushUp(x);}inline void Access(int x) { // 辅助树上打通 x 到根的路径(即 x 到根变为实链)for (int p = 0; x; p = x, x = f[x]) {Splay(x); ch[x][1] = p; PushUp(x);}}inline void MakeRoot(int x) { // 钦定 x 为辅助树根Access(x); Splay(x); PushRev(x);}inline int FindRoot(int x) { // 找 x 所在辅助树根Access(x); Splay(x);while (ch[x][0]) PushDown(x), x = ch[x][0];Splay(x); // 不加复杂度会假return x;}inline void Split(int x, int y) { // 把 x 到 y 的路径提出来, 并以 y 为 Splay 根MakeRoot(x); Access(y); Splay(y);}inline bool Link(int x, int y) { // 连接 x,y 两点MakeRoot(x);if (FindRoot(y) == x) return false;f[x] = y;return true;}inline bool Cut(int x, int y) { // x,y 断边MakeRoot(x);if (FindRoot(y) == x && f[y] == x && !ch[y][0]) {f[y] = ch[x][1] = 0; PushUp(x);return true;}return false;}// 如果保证合法/*inline void Link(int x,int y) {MakeRoot(x); MakeRoot(y); f[x]=y;}inline void Cut(int x,int y) {MakeRoot(x); Access(y); Splay(y); ch[y][0]=f[x]=0;}*//*void Print(int x) {if(ch[x][0]) Print(ch[x][0]);printf("%d,",x);if(ch[x][1]) Print(ch[x][1]);}*/}using namespace LCT;int n, m;int main() {red(n); red(m);for (int i = 1; i <= n; ++i) red(val[i]);for (int i = 1; i <= m; ++i) {int op, x, y; red(op); red(x); red(y);switch (op) {case 0: Split(x, y); printf("%d\n", dat[y]); break;case 1: Link(x, y); break;case 2: Cut(x, y); break;case 3: Splay(x); val[x] = y; break;}}}
/* 左偏树 (可并堆)+ 左偏树是一棵二叉树,有堆的性质+ 每个节点左儿子dist >= 右儿子dist+ 每个节点的 dist 都等于其右儿子的 dist 加一*/#include <bits/stdc++.h>#define ls(x) t[x].ch[0]#define rs(x) t[x].ch[1]using namespace std;const int N = 100010;struct node {int rt, ch[2], d, val;/* other tags */node() {}} t[N];int n, m;void settag(int x, int vl) {if (!x) { /* set tag */ }}void pushdown(int x) {/* pushdown tags */}int merge(int x, int y) {if (!x || !y) return x + y;if (t[x].val > t[y].val || (t[x].val == t[y].val && x > y)) swap(x, y);pushdown(x); rs(x) = merge(rs(x), y); t[x].rt = t[ls(x)].rt = t[rs(x)].rt = x;if (t[ls(x)].d < t[rs(x)].d) swap(ls(x), rs(x));t[x].d = t[rs(x)].d + 1;return x;}int pop(int x) {pushdown(x);return merge(t[x].ch[0], t[x].ch[1]);}int findrt(int u) {return u == t[u].rt ? u : t[u].rt = findrt(t[u].rt);}int main() {return 0;}
// 李超线段树 luogu-P4097 [HEOI2013]Segment#include <bits/stdc++.h>#define ls (x<<1)#define rs (x<<1|1)template<typename _Tp>inline void red(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}using namespace std;typedef long long ll;typedef double db;const int N = 100010;const int M = 40000;struct line {db k, b;} lin[N];db val(int id, db X) {return lin[id].k * X + lin[id].b;}int D[N << 2], n, id;void modify(int L, int R, int id, int l = 1, int r = M - 1, int x = 1) {if (L <= l && r <= R) {int mid = (l + r) >> 1, lid = D[x];db lst = val(D[x], mid), now = val(id, mid);if (l == r) {if (now > lst) D[x] = id; return ;}if (lin[id].k > lin[D[x]].k) {if (now > lst) D[x] = id, modify(L, R, lid, l, mid, ls); // id->lidelse modify(L, R, id, mid + 1, r, rs);} else if (lin[id].k < lin[D[x]].k) {if (now > lst) D[x] = id, modify(L, R, lid, mid + 1, r, rs); // id->lidelse modify(L, R, id, l, mid, ls);} else if (lin[id].b > lin[D[x]].k) D[x] = id;return ;}int mid = (l + r) >> 1;if (L <= mid) modify(L, R, id, l, mid, x << 1);if (R > mid) modify(L, R, id, mid + 1, r, x << 1 | 1);}int gmax(int x, int y, int ps) {if (val(x, ps) > val(y, ps)) return x;if (val(x, ps) < val(y, ps)) return y;return (x < y) ? x : y;}int query(int ps, int l = 1, int r = M - 1, int x = 1) {if (l == r) return D[x];int mid = (l + r) >> 1, ret = D[x], t = 0;if (ps <= mid)t = query(ps, l, mid, ls);elset = query(ps, mid + 1, r, rs);return gmax(ret, t, ps);}int main() {red(n);int lstans = 0, tot = 0;for (int i = 1; i <= n; ++i) {int op; red(op);if (op == 0) {++tot; int k; red(k); // 询问 x=k 最大交点k = (k + lstans - 1) % 39989 + 1;lstans = query(k);printf("%d\n", lstans);} else {int x0, y0, x1, y1; ++id; // 添加线段red(x0); red(y0); red(x1); red(y1);x0 = (x0 + lstans - 1) % 39989 + 1; x1 = (x1 + lstans - 1) % 39989 + 1;y0 = (y0 + lstans - 1) % (int)(1e9) + 1; y1 = (y1 + lstans - 1) % (int)(1e9) + 1;if (x0 > x1) swap(x0, x1), swap(y0, y1);if (x0 == x1) {lin[id].k = 0; lin[id].b = max(y1, y0);} else {lin[id].k = (db)(y1 - y0) / (db)(x1 - x0);lin[id].b = (db)y1 - lin[id].k * (db)x1;}modify(x0, x1, id);}}return 0;}
/*__gnu_pbds :: priority_queue 堆 使用指南========================================================================================================__gnu_pbds ::priority_queue<_Tv, Cmp_Fn = std::less<_Tv>, Tag = pairing_heap_tag,Allocator = std::allocator<char> >_Tv: 储存的元素类型Cmp_Fn: 比较函子,默认 std::less<_Tv> 为大根堆Tag: 堆的类型(默认且建议 pairing_heap_tag)Allocator: 空间分配器类型(不用改)push(),pop(),top(),size(),empty() 与 std::priority_queue 类似join(other) 将 other 加入当前堆,other 堆被删除(前提是两棵树的类型一样)modify(it, key) 修改迭代器 it 所指的 key,并对底层储存结构进行排序erase(it) 把迭代器 it 位置的键值从堆中擦除begin(),end() 返回可以用来遍历的迭代器,不保证有序!且只要进行过修改操作就会变========================================================================================================*/#include <bits/stdc++.h>#include <ext/pb_ds/priority_queue.hpp>using namespace std;const int N = 100010;__gnu_pbds::priority_queue<pair<int, int>, greater<pair<int, int>>> Q[N];// 以下是用 pb_ds::tree 实现的 【模板】左偏树(可并堆) https://www.luogu.com.cn/problem/P3377int fa[N], n, m;bool del[N];int find(int u) {return fa[u] == u ? u : fa[u] = find(fa[u]);}int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= n; ++i) {int x; scanf("%d", &x);fa[i] = i, Q[i].push({x, i});}while (m--) {int op, x, y;scanf("%d", &op);if (op == 1) {scanf("%d%d", &x, &y);if (del[x] || del[y]) continue;x = find(x), y = find(y);if (x != y) {fa[x] = y;Q[y].join(Q[x]);}} else {scanf("%d", &x);if (del[x]) {puts("-1");continue;}x = find(x);printf("%d\n", Q[x].top().first);del[Q[x].top().second] = 1;Q[x].pop();}}}
/*__gnu_pbds :: tree 平衡树 使用指南========================================================================================================__gnu_pbds ::tree<Key, Mapped, Cmp_Fn = std::less<Key>, Tag = rb_tree_tag,Node_Update = null_tree_node_update,Allocator = std::allocator<char> >Key: 储存的元素类型Mapped: 填 null_type 当成 std::set, 填其他类型当成 std::mapCmp_Fn: 比较函子Tag: 树的类型(建议 rb_tree_tag)Node_Update: 更新节点的策略,默认是 null_tree_node_update使用 tree_order_statistics_node_update 来允许 order_of_key,find_by_order 方法Allocator: 空间分配器类型(不用改)insert(),erase(),lower_bound(),upper_bound(),find(),empty(),size(),begin(),end() 与 std::set 类似join(other) 将 other 加入当前树,other 树被删除(前提是两棵树的类型一样)split(val, other) 以 Cmp_Fn 比较,小于等于 val 的属于当前树,其余的属于 other 树order_of_key(x) 返回 x 以 Cmp_Fn 比较的排名(从 0 开始)find_by_order(x) 返回 Cmp_Fn 比较的排名所对应元素的迭代器 (从 0 开始)========================================================================================================*/#include <bits/stdc++.h>#include <ext/pb_ds/assoc_container.hpp>#include <ext/pb_ds/tree_policy.hpp>using namespace std;__gnu_pbds::tree<std::pair<int, int>, __gnu_pbds::null_type, std::less<std::pair<int, int>>,__gnu_pbds::rb_tree_tag,__gnu_pbds::tree_order_statistics_node_update> T;// 以下是用 pb_ds::tree 实现的 【模板】普通平衡树 https://www.luogu.com.cn/problem/P3369int Q;int main() {scanf("%d", &Q);while (Q--) {int opt, x; scanf("%d%d", &opt, &x);switch (opt) {case 1: {auto it = T.lower_bound({x + 1, 0});if (it != T.begin() && (--it)->first != x) T.insert({x, 1});else T.insert({x, it->second + 1});break;}case 2: {auto it1 = --T.lower_bound({x + 1, 0});T.erase(it1);break;}case 3: {int rk = T.order_of_key({x, 1});printf("%d\n", rk + 1);break;}case 4: {auto it = T.find_by_order(x - 1);printf("%d\n", it->first);break;}case 5: {auto it = --T.lower_bound({x, 0});printf("%d\n", it->first);break;}case 6: {auto it = T.lower_bound({x + 1, 0});printf("%d\n", it->first);break;}default:break;}// for (auto i : T) {// printf("%d[%d] ", i.first, i.second);// }// puts("");}return 0;}
// 可持久化数组#include <cstdio>#define ls(p) tr[p].lc#define rs(p) tr[p].rc#define re registertemplate <typename T>inline void red(T &x) {x = 0; bool f = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') f ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (T)(ch ^ 48), ch = getchar();if (f) x = -x;}using namespace std;const int N = 1000010;struct node {int lc, rc, val;} tr[N * 21]; int tot;int root[N];int n, m, a[N];int newnode() {tr[++tot] = {0, 0, 0};return tot;}void build(int p, int l = 1, int r = n) {if (l == r) return tr[p].val = a[l], void();int mid = (l + r) >> 1;build(ls(p) = newnode(), l, mid);build(rs(p) = newnode(), mid + 1, r);}void modify(int p, int q, int pos, int val, int l = 1, int r = n) {if (l == r) return tr[q].val = val, void();int mid = (l + r) >> 1;if (pos <= mid) {modify(ls(p), ls(q) = newnode(), pos, val, l, mid);rs(q) = rs(p);} else {modify(rs(p), rs(q) = newnode(), pos, val, mid + 1, r);ls(q) = ls(p);}}int query(int p, int pos, int l = 1, int r = n) {if (l == r) return tr[p].val;int mid = (l + r) >> 1;if (pos <= mid) return query(ls(p), pos, l, mid);else return query(rs(p), pos, mid + 1, r);}int main() {red(n); red(m);for (re int i = 1; i <= n; ++i) red(a[i]);root[0] = newnode(); build(root[0]);for (re int i = 1; i <= m; ++i) {re int v, op, loc, vl;red(v); red(op); red(loc);if (op == 1) {red(vl);modify(root[v], root[i] = newnode(), loc, vl);} else {printf("%d\n", query(root[v], loc));root[i] = root[v];}}}
#include <cstdio>#include <iostream>#define ls(p) tr[p].lc#define rs(p) tr[p].rc#define re registerusing namespace std;const int N = 200010;struct node {int lc, rc, val, siz;} tr[N * 41];int root[N], tot;int n, m;int newnode() {tr[++tot] = {0, 0, 0};return tot;}void build(int p, int l = 1, int r = n) {if (l == r) return tr[p].val = l, tr[p].siz = 1, void();int mid = (l + r) >> 1;build(ls(p) = newnode(), l, mid);build(rs(p) = newnode(), mid + 1, r);}void modify_fa(int p, int q, int pos, int val, int l = 1, int r = n) {if (l == r) return tr[q].val = val, tr[q].siz = tr[p].siz, void();int mid = (l + r) >> 1;if (pos <= mid) {modify_fa(ls(p), ls(q) ? ls(q) : ls(q) = newnode(), pos, val, l, mid);if (rs(q) == 0)rs(q) = rs(p);} else {modify_fa(rs(p), rs(q) ? rs(q) : rs(q) = newnode(), pos, val, mid + 1, r); if (ls(q) == 0)ls(q) = ls(p);}}void modify_dep(int p, int q, int pos, int siz, int l = 1, int r = n) {if (l == r) return tr[q].siz = siz, tr[q].val = tr[p].val, void();int mid = (l + r) >> 1;if (pos <= mid) {modify_dep(ls(p), ls(q) ? ls(q) : ls(q) = newnode(), pos, siz, l, mid);if (rs(q) == 0)rs(q) = rs(p);} else {modify_dep(rs(p), rs(q) ? rs(q) : rs(q) = newnode(), pos, siz, mid + 1, r); if (ls(q) == 0)ls(q) = ls(p);}}// return the node numberint query(int p, int pos, int l = 1, int r = n) {if (l == r) return p;int mid = (l + r) >> 1;if (pos <= mid) return query(ls(p), pos, l, mid);else return query(rs(p), pos, mid + 1, r);}int find(int rt, int u) {int pa = query(rt, u);if (tr[pa].val == u) return u;return find(rt, tr[pa].val);}int main() {scanf("%d%d", &n, &m);root[0] = newnode(); build(root[0]);for (re int i = 1; i <= m; ++i) {re int opt, a, b;scanf("%d%d", &opt, &a);if (opt == 1) { // 合并 a,bscanf("%d", &b);root[i] = newnode();int f1 = find(root[i - 1], a), f2 = find(root[i - 1], b);int sz1 = tr[query(root[i - 1], f1)].siz, sz2 = tr[query(root[i - 1], f2)].siz;if (f1 != f2) {if (sz1 > sz2) swap(f1, f2), swap(sz1, sz2);modify_fa(root[i - 1], root[i], f1, f2);modify_dep(root[i - 1], root[i], f2, sz1 + sz2);} elseroot[i] = root[i - 1];}if (opt == 2) // 回到状态 aroot[i] = root[a];if (opt == 3) { // 询问 a,b 是否在同一集合scanf("%d", &b);root[i] = root[i - 1];int f1 = find(root[i], a), f2 = find(root[i], b);printf("%d\n", f1 == f2);}}return 0;}
// 主席树,区间第 k 大#include <cstdio>#include <algorithm>#define ls(p) tr[p].lc#define rs(p) tr[p].rc#define re registertemplate <typename T>inline void red(T &x) {x = 0; bool f = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') f ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (T)(ch ^ 48), ch = getchar();if (f) x = -x;}using namespace std;const int N = 200010;struct node {int cnt, lc, rc;} tr[N * 18]; int root[N], tot;int a[N], b[N], tt, n, q;int newnode() { tr[++tot] = {0, 0, 0}; return tot;}void pushup(int p) {tr[p].cnt = tr[ls(p)].cnt + tr[rs(p)].cnt;}void modify(int p, int q, int val, int l = 1, int r = tt) {if (l == r) return (p == 0) ? tr[q].cnt = 1 : tr[q].cnt = tr[p].cnt + 1, void();int mid = (l + r) >> 1;if (val <= mid) {modify(ls(p), ls(q) = newnode(), val, l, mid);rs(q) = rs(p);} else {modify(rs(p), rs(q) = newnode(), val, mid + 1, r);ls(q) = ls(p);}pushup(q);}int query(int p, int q, int k, int l = 1, int r = tt) {if (l == r) return b[l];int mid = (l + r) >> 1, t = tr[ls(q)].cnt - tr[ls(p)].cnt;return (k <= t) ? query(ls(p), ls(q), k, l, mid) : query(rs(p), rs(q), k - t, mid + 1, r);}int main() {red(n); red(q);for (re int i = 1; i <= n; ++i) red(a[i]), b[i] = a[i];sort(b + 1, b + n + 1);tt = unique(b + 1, b + n + 1) - b - 1;for (re int i = 1; i <= n; ++i) a[i] = lower_bound(b + 1, b + tt + 1, a[i]) - b;root[0] = newnode();for (re int i = 1; i <= n; ++i) {root[i] = newnode();modify(root[i - 1], root[i], a[i]);}for (re int i = 1; i <= q; ++i) {re int l, r, k; red(l); red(r); red(k);printf("%d\n", query(root[l - 1], root[r], k));}return 0;}
// 期望 O(n)-O(1) RMQ// luogu P3793 由乃救爷爷#include <cstdio>#define re register// -------------- ReadIN ----------------namespace GenHelper {unsigned z1, z2, z3, z4, b;unsigned rand_() {b = ((z1 << 6)^z1) >> 13;z1 = ((z1 & 4294967294U) << 18)^b;b = ((z2 << 2)^z2) >> 27;z2 = ((z2 & 4294967288U) << 2)^b;b = ((z3 << 13)^z3) >> 21;z3 = ((z3 & 4294967280U) << 7)^b;b = ((z4 << 3)^z4) >> 12;z4 = ((z4 & 4294967168U) << 13)^b;return (z1 ^ z2 ^ z3 ^ z4);}}void srand(unsigned x) {using namespace GenHelper; z1 = x; z2 = (~x) ^ 0x233333333U; z3 = x ^ 0x1234598766U; z4 = (~x) + 51;}int read() {using namespace GenHelper;int a = rand_() & 32767;int b = rand_() & 32767;return a * 32768 + b;}// ----------- END ReadIN -------------typedef unsigned long long ull;int n, m, s;// ------------ BEGIN RMQ -------------const int N = 20000010;int a[N];namespace RMQ {inline int gmax(int x, int y) {return a[x] > a[y] ? x : y;}const int B = 4434; // B 大概取 log2(n) or sqrt(n) ?? 怕被卡的话随机微调块长const int M = 16;int bl[N], F[M][N / B + 10], ps[N], pre[N], suf[N], LOG[N], tot;// bl 属于哪个块,F 块间ST表 ps块内最值下标 pre/suf 块内前缀/后缀最值void init() {for (re int i = 1; i <= n; ++i) bl[i] = (i - 1) / B + 1;for (re int i = 1; i <= n;++i)(bl[i] != bl[i - 1]) ? (pre[i] = i, ps[bl[i - 1]] = pre[i - 1]) : (pre[i] = gmax(pre[i - 1], i));for (re int i = 1, j = B; j <= n; ++i, j += B) ps[i] = pre[j];tot = bl[n]; ps[tot] = pre[n];for (re int i = n; i >= 1; --i)(bl[i] != bl[i + 1]) ? (suf[i] = i) : (suf[i] = gmax(suf[i + 1], i));LOG[0] = -1;for (re int i = 1; i <= tot; ++i) LOG[i] = LOG[i >> 1] + 1;for (re int i = 1; i <= tot; ++i) F[0][i] = ps[i];for (re int j = 1; j <= LOG[tot]; ++j) {for (re int i = 1; i <= tot; ++i) {if (i + (1 << j) - 1 > tot) break;F[j][i] = gmax(F[j - 1][i], F[j - 1][i + (1 << (j - 1))]);}}}inline int ask(int l, int r) { // 返回区间最值位置if (bl[l] == bl[r]) {int p = l;for (re int i = l + 1; i <= r; ++i) p = gmax(p, i);return p;}if (bl[l] + 1 == bl[r]) return gmax(suf[l], pre[r]);int L = bl[l] + 1, R = bl[r] - 1;int k = LOG[R - L + 1];return gmax(gmax(F[k][L], F[k][R - (1 << k) + 1]), gmax(suf[l], pre[r]));}}// -------------- END RMQ --------------inline void swap(int &l, int &r) {l ^= r; r ^= l; l ^= r;}int main() {scanf("%d%d%d", &n, &m, &s);srand(s);for (re int i = 1; i <= n; ++i) a[i] = read();RMQ::init();ull ANS = 0;for (re int i = 1, l, r; i <= m; ++i) {l = read() % n + 1, r = read() % n + 1;(l > r) &&(swap(l, r), 1);ANS += a[RMQ::ask(l, r)];}printf("%llu\n", ANS);}
/** seg-beats 吉司机线段树* 区间最值操作* 支持 区间取min,区间取max,区间加减,区间求和,区间最小/大* 复杂度 O(m log n)*/#include <bits/stdc++.h>#define ls (x << 1)#define rs (x << 1 | 1)#define mid ((l + r) >> 1)template <typename Tp>inline void read(Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') { if (ch == '-') fg ^= 1; ch = getchar(); }while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}template <typename Tp, typename... Args>void read(Tp &t, Args &...args) { read(t); read(args...); }template <typename Tp>inline void write(Tp x, char ch = '\n') {static char buf[128]; int tot = 0;if (x < 0) x = -x, putchar('-');while (x) buf[tot++] = '0' + x % 10, x /= 10;if (tot == 0) putchar('0');while (tot--) putchar(buf[tot]);if (ch) putchar(ch);}using namespace std;typedef long long ll;const int N = 500010;const int inf = 0x3f3f3f3f;struct datmn {int fi, se, cnt;datmn() {fi = se = inf; cnt = 0;}void ins(int x, int c) {if (x < fi) se = fi, cnt = c, fi = x;else if (x == fi) cnt += c;else if (x < se) se = x;}friend datmn operator+(const datmn &a, const datmn &b) {datmn r = a; r.ins(b.fi, b.cnt); r.ins(b.se, 0); return r;}};struct datmx {int fi, se, cnt;datmx() {fi = se = -inf; cnt = 0;}void ins(int x, int c) {if (x > fi) se = fi, cnt = c, fi = x;else if (x == fi) cnt += c;else if (x > se) se = x;}friend datmx operator+(const datmx &a, const datmx &b) {datmx r = a; r.ins(b.fi, b.cnt); r.ins(b.se, 0); return r;}};struct node {datmn mn; datmxmx; // mn: (最小值,严格次小值,最小值个数) , mx: (最大值,严格次大值,最大值个数)ll sum; int addmn, addmx, add,len; // sum 区间和,addmn 最小值lazytag,addmx 最大值lazytag,add 其他数 lazytag,len 区间长度} t[N << 2];// ostream &operator<<(ostream& out, const datmx &d) {// return out << "dat{ " << d.fi << " (" << d.cnt << ") ," << d.se << " } ";// }// ostream &operator<<(ostream& out, const datmn &d) {// return out << "dat{ " << d.fi << " (" << d.cnt << ") ," << d.se << " } ";// }// ostream &operator<<(ostream& out, const node &d) {// return out << "mn" << d.mn << "mx" << d.mx << " sum=" << d.sum << " addmn=" << d.addmn << " addmx=" << d.addmx << " add=" << d.add << " ";// }int n, m, a[N];void pushup(int x) {t[x].mx = t[ls].mx + t[rs].mx;t[x].mn = t[ls].mn + t[rs].mn;t[x].sum = t[ls].sum + t[rs].sum;}void build(int l = 1, int r = n, int x = 1) {t[x].add = t[x].addmn = t[x].addmx = 0;t[x].len = r - l + 1;if (l == r) {t[x].mx = datmx(); t[x].mx.ins(a[l], 1);t[x].mn = datmn(); t[x].mn.ins(a[l], 1);t[x].sum = a[l];return;}build(l, mid, ls); build(mid + 1, r, rs);pushup(x);}void update(int x, int vn, int vx, int v) { // vn: addmn, vx: addmx, v: addif (t[x].mn.fi ==t[x].mx.fi) { // 所有数相同特判,此时最大值 tag 和最小值 tag 应该相同且不等于其他值 tagif (vn == v) vn = vx;else vx = vn;t[x].sum += (ll)vn * t[x].mn.cnt;} else t[x].sum += (ll)vn * t[x].mn.cnt + (ll) vx * t[x].mx.cnt + (ll)v * (t[x].len - t[x].mn.cnt -t[x].mx.cnt);if (t[x].mn.se == t[x].mx.fi) t[x].mn.se += vx; // 次小值 = 最大值,应该用最大值 tag 处理else if (t[x].mn.se != inf) t[x].mn.se += v;if (t[x].mx.se == t[x].mn.fi) t[x].mx.se += vn; // 次大值同理else if (t[x].mx.se != -inf) t[x].mx.se += v;t[x].mn.fi += vn; t[x].mx.fi += vx;t[x].addmn += vn; t[x].addmx += vx; t[x].add += v;}void pushdown(int x) {int mn = min(t[ls].mn.fi, t[rs].mn.fi);int mx = max(t[ls].mx.fi, t[rs].mx.fi);update(ls, (mn == t[ls].mn.fi) ? t[x].addmn : t[x].add, (mx == t[ls].mx.fi) ? t[x].addmx : t[x].add,t[x].add);update(rs, (mn == t[rs].mn.fi) ? t[x].addmn : t[x].add, (mx == t[rs].mx.fi) ? t[x].addmx : t[x].add,t[x].add);t[x].add = t[x].addmn = t[x].addmx = 0;}void modifyadd(int L, int R, int v, int l = 1, int r = n, int x = 1) {if (r < L || R < l) return ;if (L <= l && r <= R) return update(x, v, v, v);pushdown(x);modifyadd(L, R, v, l, mid, ls);modifyadd(L, R, v, mid + 1, r, rs);pushup(x);}void modifymin(int L, int R, int v, int l = 1, int r = n, int x = 1) {if (r < L || R < l) return ;if (L <= l && r <= R && v > t[x].mx.se) {if (v >= t[x].mx.fi) return ;update(x, 0, v - t[x].mx.fi, 0);return;}pushdown(x);modifymin(L, R, v, l, mid, ls);modifymin(L, R, v, mid + 1, r, rs);pushup(x);}void modifymax(int L, int R, int v, int l = 1, int r = n, int x = 1) {if (r < L || R < l) return ;if (L <= l && r <= R && v < t[x].mn.se) {if (v <= t[x].mn.fi) return;update(x, v - t[x].mn.fi, 0, 0);return;}pushdown(x);modifymax(L, R, v, l, mid, ls);modifymax(L, R, v, mid + 1, r, rs);pushup(x);}int querymax(int L, int R, int l = 1, int r = n, int x = 1) {if (r < L || R < l) return -inf;if (L <= l && r <= R) return t[x].mx.fi;pushdown(x);return max(querymax(L, R, l, mid, ls), querymax(L, R, mid + 1, r, rs));}int querymin(int L, int R, int l = 1, int r = n, int x = 1) {if (r < L || R < l) return inf;if (L <= l && r <= R) return t[x].mn.fi;pushdown(x);return min(querymin(L, R, l, mid, ls), querymin(L, R, mid + 1, r, rs));}ll querysum(int L, int R, int l = 1, int r = n, int x = 1) {if (r < L || R < l) return 0;if (L <= l && r <= R) return t[x].sum;pushdown(x);return querysum(L, R, l, mid, ls) + querysum(L, R, mid + 1, r, rs);}void print(int l = 1, int r = n, int x = 1) {if (l == r) {cerr << t[x].sum << " ";return ;}pushdown(x);print(l, mid, ls);print(mid + 1, r, rs);}signed main() {read(n);for (int i = 1; i <= n; ++i) read(a[i]);build();read(m);for (int i = 1; i <= m; ++i) {int op, l, r, x;read(op, l, r);if (op <= 3) read(x);switch (op) {case 1:modifyadd(l, r, x);break;case 2:modifymax(l, r, x);break;case 3:modifymin(l, r, x);break;case 4:write(querysum(l, r));break;case 5:write(querymax(l, r));break;case 6:write(querymin(l, r));break;}}return 0;}
// 线段树套主席树#include <bits/stdc++.h>#define ls(p) t[p].l#define rs(p) t[p].r#define lc (x << 1)#define rc (x << 1 | 1)#define mid ((l + r) >> 1)using namespace std;template <typename Tp> void read(Tp &x) {x = 0; char ch = getchar(); int f = 0;while (ch < '0' || ch > '9') { if (ch == '-') f ^= 1; ch = getchar(); }while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (Tp)(ch ^ 48), ch = getchar();if (f) x = -x;}template <typename Tp, typename... Args>void read(Tp &t, Args &... args) { read(t); read(args...); }const int N = 50010;const int INF = 2147483647;const int MAX = 1e8;const int MIN = -1e8;int n, m, a[N];struct node {int l, r, sum;} t[N * 450];int rt[N << 2], tot;int newnode() {t[++tot] = { 0, 0, 0 };return tot;}void modify(int &p, int val, int cnt, int l = MIN, int r = MAX) {if (!p) p = newnode();if (l == r) return t[p].sum += cnt, void();if (val <= mid) modify(ls(p), val, cnt, l, mid);else modify(rs(p), val, cnt, mid + 1, r);t[p].sum = t[ls(p)].sum + t[rs(p)].sum;}int query(int p, int L, int R, int l = MIN, int r = MAX) {if (!p || L > R) return 0;if (L <= l && r <= R) return t[p].sum;if (L <= mid && R > mid) return query(ls(p), L, R, l, mid) + query(rs(p), L, R, mid + 1, r);return (L <= mid) ? query(ls(p), L, R, l, mid) : query(rs(p), L, R, mid + 1, r);}void Build(int l = 1, int r = n, int x = 1) {for (int i = l; i <= r; ++i) modify(rt[x], a[i], 1);if (l == r) return ;Build(l, mid, lc);Build(mid + 1, r, rc);}// 返回 [L, R] 中 <= k 的个数int Rank(int L, int R, int k, int l = 1, int r = n, int x = 1) {if (L <= l && r <= R) return query(rt[x], 0, k);int ret = 0;if (L <= mid) ret = Rank(L, R, k, l, mid, lc);if (R > mid) ret += Rank(L, R, k, mid + 1, r, rc);return ret;}vector<int> nods;void work(int L, int R, int l = 1, int r = n, int x = 1) {if (L <= l && r <= R) return nods.push_back(rt[x]);if (L <= mid) work(L, R, l, mid, lc);if (R > mid) work(L, R, mid + 1, r, rc);}// 返回 [L, R] 中排名第 k 的数,不合法则 -INFint Kth(int L, int R, int k) {if (k <= 0 || k > R - L + 1) return -INF;nods.clear();work(L, R);int l = MIN, r = MAX, cnt;while (l < r) {cnt = 0;for (int i = 0; i < (int)nods.size(); ++i) cnt += t[ls(nods[i])].sum;if (cnt >= k) {for (int i = 0; i < (int)nods.size(); ++i) nods[i] = ls(nods[i]);r = mid;} else {for (int i = 0; i < (int)nods.size(); ++i) nods[i] = rs(nods[i]);l = mid + 1;k -= cnt;}}return l;}void Modify(int pos, int lst, int val, int l = 1, int r = n, int x = 1) {modify(rt[x], lst, -1);modify(rt[x], val, 1);if (l == r) return ;if (pos <= mid) Modify(pos, lst, val, l, mid, lc);else Modify(pos, lst, val, mid + 1, r, rc);}int main() {read(n, m);for (int i = 1; i <= n; ++i) read(a[i]);Build();for (int cs = 1; cs <= m; ++cs) {int op, x, y, z, k;read(op, x, y);switch (op) {case 1:read(z);printf("%d\n", Rank(x, y, z - 1) + 1);break;case 2:read(z);printf("%d\n", Kth(x, y, z));break;case 3:Modify(x, a[x], y); a[x] = y;break;case 4:read(z);k = Kth(x, y, Rank(x, y, z - 1));printf("%d\n", k == -INF ? -INF : k);break;case 5:read(z);k = Kth(x, y, Rank(x, y, z) + 1);printf("%d\n", k == -INF ? INF : k);break;}}return 0;}/*1. [l, r] k 排名找每个区间比 k 小的个数2. [l, r] 排名为 k所有区间捞出来,线段树二分?3. 单点修改下标 pos 的数改为 k改就是了4. [l, r] x 的前驱Kth(Rank(z - 1))5. [l, r] x 的后继Kyh(Rank(z) + 1)*/
// 区间加/乘法#include <stdio.h>#include <iostream>using namespace std;const int N = 100000;int n, m;long long mod;long long sum[N << 2], mult[N << 2], add[N << 2], a[N];void pushup(int x);void pushdown(int x, int l, int r, int m);void build(int x, int l, int r) {add[x] = 0; mult[x] = 1;if (l == r) {sum[x] = a[l];return ;}int m = (l + r) >> 1;build(x << 1, l, m);build(x << 1 | 1, m + 1, r);pushup(x);}void init() {scanf("%d%d%lld", &n, &m, &mod);for (int i = 1; i <= n; i++)scanf("%lld", &a[i]);build(1, 1, n);}void pushup(int x) {sum[x] = (sum[x << 1] + sum[x << 1 | 1]) % mod;}void pushdown(int x, int l, int r, int m) {//left sonsum[x << 1] = (sum[x << 1] * mult[x] + (m - l + 1) * add[x]) % mod;mult[x << 1] = (mult[x << 1] * mult[x]) % mod;add[x << 1] = (add[x << 1] * mult[x] + add[x]) % mod;//right sonsum[x << 1 | 1] = (sum[x << 1 | 1] * mult[x] + (r - m) * add[x]) % mod;mult[x << 1 | 1] = (mult[x << 1 | 1] * mult[x]) % mod;add[x << 1 | 1] = (add[x << 1 | 1] * mult[x] + add[x]) % mod;//clearadd[x] = 0;mult[x] = 1;}void modify(int L, int R, long long val, int x, int l, int r) { //addif (L <= l && r <= R) {add[x] = (add[x] + val) % mod;sum[x] = (sum[x] + val * (long long)(r - l + 1)) % mod;return ;}int m = (l + r) >> 1;pushdown(x, l, r, m);if (L <= m)modify(L, R, val, x << 1, l, m);if (R > m)modify(L, R, val, x << 1 | 1, m + 1, r);pushup(x);}void modify1(int L, int R, long long val, int x, int l, int r) { //multif (L <= l && r <= R) {sum[x] = (sum[x] * val) % mod;add[x] = (add[x] * val) % mod;mult[x] = (mult[x] * val) % mod;return ;}int m = (l + r) >> 1;pushdown(x, l, r, m);if (L <= m)modify1(L, R, val, x << 1, l, m);if (R > m)modify1(L, R, val, x << 1 | 1, m + 1, r);pushup(x);}long long query(int L, int R, int x, int l, int r) {if (L <= l && r <= R)return sum[x] % mod;int m = (l + r) >> 1;pushdown(x, l, r, m);long long ret = 0;if (L <= m)ret += query(L, R, x << 1, l, m);if (R > m)ret += query(L, R, x << 1 | 1, m + 1, r);return ret % mod;}int main() {init();while (m--) {int op, x, y;long long k;scanf("%d", &op);if (op == 1) { //multscanf("%d%d%lld", &x, &y, &k);modify1(x, y, k, 1, 1, n);}if (op == 2) { //addscanf("%d%d%lld", &x, &y, &k);modify(x, y, k, 1, 1, n);}if (op == 3) { //queryscanf("%d%d", &x, &y);printf("%lld\n", query(x, y, 1, 1, n));}}}
/*数组实现的普通Treap2020-6-19by fxz*/#include <bits/stdc++.h>using namespace std;struct treap {private:// N 为节点数const static int N = 100010;const static int INF = 0x7fffffff;// l,r左右儿子下标 val节点关键码 rnd随机权值 cnt副本数 siz子树大小 tot节点数 root树根int l[N], r[N], val[N], rnd[N], cnt[N], siz[N], tot, root;// 回收利用删除节点int eat[N], et;//回收节点void del(int &p) {eat[++et] = p; p = 0;}//开点int newn(int vl) {int t = et > 0 ? eat[et--] : ++tot;val[t] = vl;rnd[t] = rand();cnt[t] = siz[t] = 1;return t;}//上载,更新节点void updata(int p) {siz[p] = siz[l[p]] + siz[r[p]] + cnt[p];}//右旋void zig(int &p) {int q = l[p]; l[p] = r[q]; r[q] = p; p = q; updata(r[p]), updata(p);}//左旋void zag(int &p) {int q = r[p]; r[p] = l[q]; l[q] = p; p = q; updata(l[p]), updata(p);}//获取排名int rank(int vl, int p) {if (p == 0) return 0;if (vl == val[p]) return siz[l[p]];if (vl < val[p]) return rank(vl, l[p]);return rank(vl, r[p]) + siz[l[p]] + cnt[p];}//获取数值int value(int rk, int p) {if (p == 0) return INF;if (siz[p[l]] >= rk) return value(rk, l[p]);if (siz[p[l]] + cnt[p] >= rk) return val[p];return value(rk - siz[l[p]] - cnt[p], r[p]);}//插入void _insert(int vl, int &p) {if (p == 0) {p = newn(vl);return ;}if (vl == val[p]) {cnt[p]++; updata(p);return ;}if (vl < val[p]) {_insert(vl, l[p]);if (rnd[p] < rnd[l[p]]) zig(p);} else {_insert(vl, r[p]);if (rnd[p] < rnd[r[p]]) zag(p);}updata(p);}//删除void _remove(int vl, int &p) {if (p == 0) return ;if (vl == val[p]) {if (cnt[p] > 1) {cnt[p]--; updata(p);return ;}if (l[p] || r[p]) {if (r[p] == 0 || rnd[l[p]] > rnd[r[p]]) zig(p), _remove(vl, r[p]);else zag(p), _remove(vl, l[p]);updata(p);} else del(p);return ;}vl < val[p] ? _remove(vl, l[p]) : _remove(vl, r[p]);updata(p);}public://重置,初始化void build() {tot = et = 0;newn(-INF), newn(INF);root = 1, r[1] = 2;updata(root);}//获取某值的排名(定义为比它小的个数+1)int getrank(int vl) {return rank(vl, root);}//获取排名为rk值int getval(int rk) {return value(rk + 1, root);}//插入一个值,可重复void insert(int vl) {_insert(vl, root);}//输出某值前驱,若无则-INFint getpre(int vl) {int ret = 1, p = root; // val[1]==-INFwhile (p) {if (vl == val[p]) {if (l[p] > 0) {p = l[p];while (r[p] > 0) p = r[p];ret = p;}}if (val[p] < vl && val[p] > val[ret]) ret = p;p = vl < val[p] ? l[p] : r[p];}return val[ret];}//输出某值后继,若无则INFint getnxt(int vl) {int ret = 2, p = root; //val[2]=INFwhile (p) {if (vl == val[p]) {if (r[p] > 0) {p = r[p];while (l[p] > 0) p = l[p];ret = p;}}if (val[p] > vl && val[p] < val[ret]) ret = p;p = vl < val[p] ? l[p] : r[p];}return val[ret];}//删除某值,如果出现多个只删一个void remove(int vl) {_remove(vl, root);}//返回元素个数,包括重复元素int size() {return siz[root] - 2;}//判断是否为空bool empty() {return size() == 0;}} tp;int n;int main() {tp.build();scanf("%d", &n);while (n--) {int op, x;scanf("%d%d", &op, &x);switch (op) {case 1:tp.insert(x); break;case 2:tp.remove(x); break;case 3:printf("%d\n", tp.getrank(x)); break;case 4:printf("%d\n", tp.getval(x)); break;case 5:printf("%d\n", tp.getpre(x)); break;case 6:printf("%d\n", tp.getnxt(x)); break;}}}
/*维护异或和的 01 trie支持插入,删除,修改,全局+1*/#include <bits/stdc++.h>namespace trie {#define ls(x) ch[x][0]#define rs(x) ch[x][1]const int N = 600010;const int DEP = 22;int ch[N * DEP][2], w[N * DEP], xorw[N * DEP], sz;int newnode() {++sz; ch[sz][0] = ch[sz][1] = 0; w[sz] = xorw[sz] = 0; return sz;}void pushup(int p) {w[p] = xorw[p] = 0;if (ls(p)) {w[p] += w[ls(p)];xorw[p] ^= xorw[ls(p)] << 1;}if (rs(p)) {w[p] += w[rs(p)];xorw[p] ^= (xorw[rs(p)] << 1) | (w[rs(p)] & 1);}}void insert(int &p, int x, int d = 0) {if (!p) p = newnode();if (d >= DEP) return ++w[p], void();insert(ch[p][x & 1], x >> 1, d + 1);pushup(p);}void erase(int p, int x, int d = 0) {if (d >= DEP) return --w[p], void();erase(ch[p][x & 1], x >> 1, d + 1);pushup(p);}// merge q to pint merge(int p, int q) {if (!p || !q) return p + q;w[p] += w[q]; xorw[p] ^= xorw[q];ls(p) = merge(ls(p), ls(q));rs(p) = merge(rs(p), rs(q));return p;}void addall(int p) {swap(ls(p), rs(p));if (ls(p)) addall(ls(p));pushup(p);}int xorsum(int p) {return xorw[p];}}int main() {return 0;}
#include <bits/stdc++.h>#define il inlineusing namespace std;typedef double db;const db eps = 1e-8;il int sign(const db &num) {return (num > eps) - (num < -eps);} // 判断符号,为正则 1 为负则 -1 为零则零il int cmp(const db &a, const db &b) {return sign(a - b);} // 比较大小struct vec { // Vector & Pointdb x, y;void input() {scanf("%lf%lf", &x, &y);}vec(const db &_x = 0, const db &_y = 0): x(_x), y(_y) {}il vec operator+(const vec &v) const {return vec(x + v.x, y + v.y);}il vec operator-(const vec &v) const {return vec(x - v.x, y - v.y);}il vec operator*(const db &a) const {return vec(x * a, y * a);}il vec operator/(const db &a) const {return vec(x / a, y / a);}il db len2() const {return x * x + y * y;}il db len() const {return hypot(x, y);} // 模长il vec turnc(db r) const {db l = len(); if (!sign(l)) return *this; r /= l; return (*this) * r;} // 改变长度bool operator<(const vec t) const {return (cmp(x, t.x) == 0) ? (cmp(y, t.y) < 0) : (cmp(x, t.x) < 0);}bool operator==(const vec t) const {return cmp(x, t.x) == 0 && cmp(y, t.y) == 0;}};typedef vec poi;il db dot(const vec &a, const vec &b) {return a.x * b.x + a.y * b.y;} // 点积il db crs(const vec &a, const vec &b) {return a.x * b.y - a.y * b.x;} // 叉积il db dis(const poi &a, const poi &b) {return (b - a).len();} // 两点距离vector<poi> pts, pois; int n;poi O;bool cmpv(poi a, poi b) { // 极角排序(这个 cmp 需要保证所有点在原点一侧)int k = sign(crs(a - O, b - O));return (k == 0) ? ((a - O).len2() < (b - O).len2()) : (k > 0);}int relat(const poi &a, const poi &b, const poi &c) { // 三点关系,判断是凸还是凹return sign(crs(b - a, c - b));}void Graham(vector<poi> pt, vector<poi> &res) { // Graham 求凸包 (极角排序+单调栈)res.clear();for (int i = 1; i < (int)pt.size(); ++i) if (pt[i] < pt[0]) swap(pt[i], pt[0]);O = pt[0];sort(pt.begin() + 1, pt.end(), cmpv);for (int i = 0; i < (int)pt.size(); ++i) {while (res.size() >= 2 && relat(res[res.size() - 2], res[res.size() - 1], pt[i]) <= 0) res.pop_back();res.push_back(pt[i]);}}db Aera(vec a, vec b, vec c) {return abs(crs(b - a, c - a));} // 三角形面积 |(*2)|db Diam(vector<poi> pt) { // 凸包直径 Diameter “旋转卡壳”int n = pt.size(), j = 0; db res = 0;if (pt.size() == 2) return (pt[0] - pt[1]).len2();pt.push_back(pt[0]);for (int i = 0; i < n; ++i) {while (Aera(pt[i], pt[i + 1], pt[(j + 1) % n]) >= Aera(pt[i], pt[i + 1], pt[j])) j = (j + 1) % n;res = max(res, max((pt[j] - pt[i]).len2(), (pt[j] - pt[i + 1]).len2()));}return res;}db Perim(vector<poi> pt) { // 凸包周长 Perimeterdb res = 0; int n = pois.size();for (int i = 0; i < n; ++i) res += dis(pois[(i == 0) ? (n - 1) : (i - 1)], pois[i]);return res;}db Area(const vector<poi> &pts) { // 任意多边形面积 (有向面积:顺负逆正)db res = 0; int n = pts.size();for (int i = 1; i < n - 1; ++i) res += crs(pts[i] - pts[0], pts[i + 1] - pts[0]);return res / 2.0;}poi Grav(const vector<poi> &pts) { // Center of Gravity 多边形质心poi g; db sumarea = 0; int n = pts.size();for (int i = 2; i < n; ++i) {db S = crs(pts[i - 1] - pts[0], pts[i] - pts[0]);g = g + (pts[0] + pts[i - 1] + pts[i]) * S;sumarea += S;}return g / (sumarea * 3);}int main() {// Readinscanf("%d", &n); pts.resize(n);for (int i = 0; i < n; ++i) pts[i].input();}
/*半平面交本代码 --> 求凸多边形面积并*/#include <bits/stdc++.h>#define il inlineusing namespace std;typedef double db;const db Pi = acos(-1.0);const db eps = 1e-7;il int sign(db num) {return (num > eps) - (num < -eps);}il int cmp(db a, db b) {return sign(a - b);}struct vec {db x, y;vec(db _x = 0, db _y = 0): x(_x), y(_y) {}il void input() {scanf("%lf%lf", &x, &y);}il vec operator+(const vec &t) const {return vec(x + t.x, y + t.y);}il vec operator-(const vec &t) const {return vec(x - t.x, y - t.y);}il vec operator*(const db &t) const {return vec(x * t, y * t);}il vec operator/(const db &t) const {return vec(x / t, y / t);}il db len2() const {return x * x + y * y;}il db len() const {return hypot(x, y);}bool operator<(const vec &t) const {return (cmp(x, t.x) == 0) ? (cmp(y, t.y) < 0) : (cmp(x, t.x) < 0);}};typedef vec poi;il db dot(const vec &a, const vec &b) {return a.x * b.x + a.y * b.y;}il db crs(const vec &a, const vec &b) {return a.x * b.y - a.y * b.x;}il db dis(const vec &a, const vec &b) {return (a - b).len();}struct lin {poi s, e; db k;lin(poi _s, vec _e): s(_s), e(_e), k(atan2((e - s).y, (e - s).x)) {}il poi operator()() const {return e - s;}};il poi cross(const lin &l1, const lin &l2) {return l1.s + l1() * crs(l2.s - l1.s, l2()) / crs(l1(), l2());}vector<lin> L; // 半平面们,统一向量左侧为半平面vector<poi> P, pts; // 多边形们int n, m;bool cmpl(lin a, lin b) { // 极角排序,极角相同靠左优先if (cmp(a.k, b.k) == 0) return sign(crs(b.e-a.s, a())) > 0;return cmp(a.k, b.k) < 0;}bool Onright(lin a, lin b, lin c) { // a,b 交点在 c 右边poi p = cross(a, b);return sign(crs(c(), p - c.s)) <= 0;}void Halfplane(vector<lin> Ls, vector<poi> &res) { // 半平面交res.clear();sort(Ls.begin(), Ls.end(), cmpl);deque<int> q;for (int i = 0; i < (int)Ls.size(); ++i) {if (i != 0 && cmp(Ls[i].k, Ls[i - 1].k) == 0) continue;while (q.size() >= 2 && Onright(Ls[q[q.size() - 2]], Ls[q.back()], Ls[i])) q.pop_back();while (q.size() >= 2 && Onright(Ls[q.front()], Ls[q[1]], Ls[i])) q.pop_front();q.push_back(i);}while (q.size() >= 2 && Onright(Ls[q[q.size() - 2]], Ls[q.back()], Ls[q.front()])) q.pop_back();while (q.size() >= 2 && Onright(Ls[q[0]], Ls[q[1]], Ls[q.back()])) q.pop_front();if (q.size() >= 2) res.push_back(cross(Ls[q.back()], Ls[q.front()]));while (q.size() >= 2) {res.push_back(cross(Ls[q[0]], Ls[q[1]]));q.pop_front();}}db Area(const vector<poi> &pts) { //多边形面积db res = 0;for (int i = 1; i < (int)pts.size() - 1; ++i) res += crs(pts[i] - pts[0], pts[i + 1] - pts[0]);return res / 2.0;}int main() {scanf("%d", &n);for (int i = 1; i <= n; ++i) {scanf("%d", &m);pts.resize(m);for (int i = 0; i < m; ++i) pts[i].input();for (int i = 0; i < m; ++i) L.push_back(lin(pts[i], pts[(i + 1) % m]));}Halfplane(L, P);db ans = Area(P);printf("%.3lf\n", ans);return 0;}
/*https://vjudge.net/problem/UVA-12304计算几何 基du础liu题 点线圆相关计算几何板子 v1.0*/#include <bits/stdc++.h>#define il inlineusing namespace std;typedef double db;const db eps = 1e-10;il int sign(const db &num) {return (num > eps) - (num < -eps);} // 判断符号,为正则 1 为负则 -1 为零则零il int cmp(const db &a, const db &b) {return sign(a - b);} // 比较大小const db Pi = acos(-1);il db R_to_D(const db &rad) {return 180.0 / Pi * rad;}il db D_to_R(const db °) {return Pi / 180.0 * deg;}struct vec { // Vector & Pointdb x, y;void input() {scanf("%lf%lf", &x, &y);}vec(const db &_x = 0, const db &_y = 0): x(_x), y(_y) {}il vec operator+(const vec &v) const {return vec(x + v.x, y + v.y);}il vec operator-(const vec &v) const {return vec(x - v.x, y - v.y);}il vec operator*(const db &a) const {return vec(x * a, y * a);}il vec operator/(const db &a) const {return vec(x / a, y / a);}il db len2() const {return x * x + y * y;}il db len() const {return hypot(x, y);} // 模长il vec unit() const {db l = len(); return (sign(l) == 0) ? (vec(0, 0)) : (*this / l); } // 单位化il vec turnc(db r) const {db l = len(); if (!sign(l)) return *this; r /= l; return (*this) * r;} // 改变长度il db angle() const { db k = atan2(y, x); if (sign(k) < 0) k += Pi; if (cmp(k, Pi) == 0) k -= Pi; return k;}bool operator<(const vec t) const {return (cmp(x, t.x) == 0) ? (cmp(y, t.y) < 0) : (cmp(x, t.x) < 0);}bool operator==(const vec t) const {return cmp(x, t.x) == 0 && cmp(y, t.y) == 0;}};typedef vec poi;struct cir { // Circlepoi O; db r;cir() {}cir(const poi &_O, const db &_r): O(_O), r(_r) {}void input() {O.input(); scanf("%lf", &r);}};struct lin { // Line & Raypoi p; vec v;lin() {}lin(const poi &_p, const vec &_v): p(_p), v(_v) {} // 直线上点p,方向向量vlin(const db &_x1, const db &_y1, const db &_x2, const db &_y2): p(_x1, _y1), v(_x2 - _x1,_y2 - _y1) {} // 直线上两点il db angle() const {return v.angle();}void input() {p.input(); v.input(); v = v - p;}};typedef lin ray;il db dot(const vec &a, const vec &b) {return a.x * b.x + a.y * b.y;} // 点积il db crs(const vec &a, const vec &b) {return a.x * b.y - a.y * b.x;} // 叉积il vec rot90(const vec &t) {return vec(-t.y, t.x);} // +90il vec rotn90(const vec &t) {return vec(t.y, -t.x);} // -90il vec rot180(const vec &t) {return vec(-t.x, -t.y);} // +180il poi cross(const lin &a, const lin &b) {return a.p + a.v * crs((b.p - a.p), b.v) / crs(a.v, b.v);} // 求两直线交点il poi foot(const lin &l, const poi &p) {return cross(lin(p, rot90(l.v)), l);} // p 到 l 的垂足il db dist(const lin &l, const poi &p) {return (p - foot(l, p)).len();} // 点到直线距离il db Helen(const db &a, const db &b, const db &c) { db p = (a + b + c) / 2; return sqrt(p * (p - a) * (p - b) * (p - c));} // 海伦公式,求三角形面积il int rela(const cir &c, const poi &p) {return cmp((c.O - p).len(), c.r) + 1;} // 点与圆关系,0:点在圆内;1:点在圆上;2:点在圆外il int rela(const cir &c, const lin &l); // 圆与直线关系il int rela(const cir &c, const lin &l); // 圆与圆关系il void cross(const cir &c, const lin &l, poi &p1, poi &p2); // 圆与直线交点void ptv(const vec &v) {printf(">>> [%.6lf,%.6lf]\n", v.x, v.y);}void ptp(const poi &p) {printf(">>> (%.6lf,%.6lf)\n", p.x, p.y);}void ptl(const lin &l) {printf(">>> (%.6lf,%.6lf) [%.6lf,%.6lf]\n", l.p.x, l.p.y, l.v.x, l.v.y);}void ptc(const cir &c) {printf(">>> (%.6lf,%.6lf) r=%0.6lf\n", c.O.x, c.O.y, c.r);}void ptt(const db &t) {printf(">>> %.6lf\n", t);}cir OutsideCircle(const poi &A, const poi &B, const poi &C) { // 外接圆poi O = cross(lin((A + B) / 2, rot90(B - A)), lin((A + C) / 2, rot90(A - C)));return cir(O, (O - A).len());}cir InsideCircle(const poi &A, const poi &B, const poi &C) { // 内切圆vec a = C - B, c = A - B, b = C - A;db p = a.len() + b.len() + c.len();db r = abs(crs(a, c) / p);poi O = (A * a.len() + B * b.len() + C * c.len()) / p;return cir(O, r);}void TangentLine(const cir &C, const poi &P, vector<lin> &res) { // 过点 P 到圆的切线res.clear();int op = cmp((C.O - P).len(), C.r);if (op < 0) return ; // P 在圆内无切线if (op == 0) {res.push_back(lin(P, rot90(C.O - P))); // P 在圆上切线与半径垂直return ;}// P 在圆外两切线vec d = P - C.O;db t = sqrt(d.len2() - C.r * C.r);db h = t * C.r / d.len(), x = C.r * h / t;poi F = C.O + d.turnc(x);res.push_back(lin(P, (F + rot90(d).turnc(h) - P)));res.push_back(lin(P, (F + rotn90(d).turnc(h) - P)));}void GetCircle(const poi &P, const lin &l, const db &r,vector<poi> &res) { // 给圆上一点,一切线,半径:求圆心res.clear();if (sign(crs(l.v, l.p - P)) == 0) { // P 在 l 上,P 为切点res.push_back(P + rot90(l.v).turnc(r));res.push_back(P + rotn90(l.v).turnc(r));return ;}poi F = foot(l, P); // F 为 P 到 l 垂足int op = cmp((P - F).len(), 2 * r);if (op > 0) return ; // P 到 l 距离大于 2rif (op == 0) { // P 到 l 距离等于 2r,PF为直径res.push_back((P + F) / 2);return ;}db t = (P - F).len() - r, d = sqrt(r * r - t * t);res.push_back(F + l.v.turnc(d) + (P - F).turnc(r));res.push_back(F - l.v.turnc(d) + (P - F).turnc(r));}void GetCircle(const lin &l1, const lin &l2, const db &r, vector<poi> &res) { // 两切线+半径:求圆心res.clear();lin l1u = lin(l1.p + rot90(l1.v).turnc(r), l1.v), l1d = lin(l1.p + rotn90(l1.v).turnc(r), l1.v);lin l2u = lin(l2.p + rot90(l2.v).turnc(r), l2.v), l2d = lin(l2.p + rotn90(l2.v).turnc(r), l2.v);res.push_back(cross(l1u, l2u)); res.push_back(cross(l1u, l2d));res.push_back(cross(l1d, l2u)); res.push_back(cross(l1d, l2d));}void CircleCross(const cir &c1, const cir &c2, vector<poi> &res) { // 求两圆交点res.clear();vec d = c2.O - c1.O;int op = cmp(c1.r + c2.r, d.len());if (op < 0) return ;if (op == 0) {res.push_back(c1.O + d.turnc(c1.r));return ;}db t = c1.r * (c1.r * c1.r + d.len2() - c2.r * c2.r) / (2.0 * c1.r * d.len());db h = sqrt(c1.r * c1.r - t * t);res.push_back(c1.O + rot90(d).turnc(h) + d.turnc(t));res.push_back(c1.O + rotn90(d).turnc(h) + d.turnc(t));}void TangentCircle(const cir &c1, const cir &c2, const db &r,vector<poi> &res) { // 给两无交圆 ,求半径为r的切圆CircleCross(cir(c1.O, c1.r + r), cir(c2.O, c2.r + r), res);}void output(vector<poi> &pois) {sort(pois.begin(), pois.end());printf("[");for (int i = 0; i < (int)pois.size(); ++i) {printf("(%.6lf,%.6lf)", pois[i].x, pois[i].y);if (i < (int)pois.size() - 1) putchar(',');}printf("]\n");}void output(vector<db> &nums) {sort(nums.begin(), nums.end());printf("[");for (int i = 0; i < (int)nums.size(); ++i) {printf("%.6lf", nums[i]);if (i < (int)nums.size() - 1) putchar(',');}printf("]\n");}string opt;int main() {while (cin >> opt) {if (opt == "CircumscribedCircle") {poi A, B, C; A.input(); B.input(); C.input();cir c = OutsideCircle(A, B, C);printf("(%.6lf,%.6lf,%.6lf)\n", c.O.x, c.O.y, c.r);} else if (opt == "InscribedCircle") {poi A, B, C; A.input(); B.input(); C.input();cir c = InsideCircle(A, B, C);printf("(%.6lf,%.6lf,%.6lf)\n", c.O.x, c.O.y, c.r);} else if (opt == "TangentLineThroughPoint") {vector<lin> lins; vector<db> degs; poi P; cir c;c.input(); P.input();TangentLine(c, P, lins);for (int i = 0; i < (int)lins.size(); ++i)degs.push_back(R_to_D(lins[i].angle()));output(degs);} else if (opt == "CircleThroughAPointAndTangentToALineWithRadius") {vector<poi> pois; poi P; lin l0; db r;P.input(); l0.input(); scanf("%lf", &r);GetCircle(P, l0, r, pois);output(pois);} else if (opt == "CircleTangentToTwoLinesWithRadius") {vector<poi> pois; lin l1, l2; db r;l1.input(); l2.input(); scanf("%lf", &r);GetCircle(l1, l2, r, pois);output(pois);} else if (opt == "CircleTangentToTwoDisjointCirclesWithRadius") {vector<poi> pois; cir c1, c2; db r;c1.input(); c2.input(); scanf("%lf", &r);TangentCircle(c1, c2, r, pois);output(pois);}}}
#include <cstdio>#include <cmath>#include <algorithm>#include <ctime>using namespace std;typedef long double db;const int N = 100010;struct vec {db x, y;vec(const db &_x = 0, const db &_y = 0): x(_x), y(_y) {}vec operator+(const vec &t) const {return vec(x + t.x, y + t.y);}vec operator-(const vec &t) const {return vec(x - t.x, y - t.y);}vec operator*(const db &t) const {return vec(x * t, y * t);}vec operator/(const db &t) const {return vec(x / t, y / t);}const db len2() const {return x * x + y * y;}const db len() const {return sqrt(len2());}};db dot(const vec &a, const vec &b) {return a.x * b.x + a.y * b.y;}db crs(const vec &a, const vec &b) {return a.x * b.y - a.y * b.x;}vec pt[N]; int n;vec rot90(vec a) {return vec(a.y, -a.x);}vec cross(vec p1, vec v1, vec p2, vec v2) {return p1 + v1 * crs(p2 - p1, v2) / crs(v1, v2);}vec get_circle(vec a, vec b, vec c) { return cross((a + b) / 2, rot90(b - a), (b + c) / 2, rot90(c - b));}void min_circle_cover(vec p[], int t) {random_shuffle(p + 1, p + n + 1);db r_2 = 0; vec O;for (int i = 1; i <= n; ++i) {if ((p[i] - O).len2() > r_2) {O = p[i], r_2 = 0;for (int j = 1; j < i; ++j) {if ((p[j] - O).len2() > r_2) {O = (p[i] + p[j]) / 2, r_2 = (p[i] - O).len2();for (int k = 1; k < j; ++k) {if ((p[k] - O).len2() > r_2) {O = get_circle(p[i], p[j], p[k]); r_2 = (p[k] - O).len2();}}}}}}printf("%.10Lf\n%.10Lf %.10Lf\n", sqrt(r_2), O.x, O.y);}int main() {srand(time(0));scanf("%d", &n);for (int i = 1; i <= n; ++i)scanf("%Lf%Lf", &pt[i].x, &pt[i].y);min_circle_cover(pt, n);}
#include <bits/stdc++.h>using namespace std;const int N = 2000100;int n, m;struct twosat {int head[N], pnt[N], nxt[N], E;int dfn[N], low[N], tis, st[N], top, col[N], co, ans[N];void add(int u, int v) {E++; pnt[E] = v; nxt[E] = head[u]; head[u] = E;}void tarjan(int u) {st[++top] = u; dfn[u] = low[u] = ++tis;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);else if (!col[v]) low[u] = min(low[u], dfn[v]);}if (low[u] == dfn[u]) {col[u] = ++co;while (st[top] != u) {col[st[top]] = co; top--;}top--;}}bool solve() {for (int i = 1; i <= 2 * n; i++) if (!dfn[i]) tarjan(i);for (int i = 1; i <= n; i++) {if (col[i] == col[i + n]) return 0;ans[i] = (col[i] > col[i + n]);}return 1;}void insert(int i, bool a, int j, bool b) {// here xi=a or xj=badd(i + n * (a ^ 1), j + b * n);add(j + n * (b ^ 1), i + a * n);// other forms// if xi=a then xj=b// add(i+a*n,j+b*n);// add(j+(b^1)*n,i+(a^1)*n);}} S;int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= m; i++) {int u, a, v, b;scanf("%d%d%d%d", &u, &a, &v, &b);S.insert(u, a, v, b);}bool fg = S.solve();if (!fg) printf("IMPOSSIBLE\n");else {printf("POSSIBLE\n");for (int i = 1; i <= n; i++) printf("%d ", S.ans[i]);printf("\n");}}
#include <bits/stdc++.h>using namespace std;template<typename T>inline void red(T &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (T)(ch ^ 48), ch = getchar();if (fg) x = -x;}template<size_t N, size_t M>struct Dinic {const int inf = 0x3f3f3f3f;int fl[M << 1], pnt[M << 1], nxt[M << 1], cur[N], head[N], dep[N], E, S, T;long long maxf;Dinic() {memset(head, -1, sizeof(head)); E = -1;}void adde(int u, int v, int c) {E++; pnt[E] = v; fl[E] = c; nxt[E] = head[u]; head[u] = E;E++; pnt[E] = u; fl[E] = 0; nxt[E] = head[v]; head[v] = E;}bool BFS(int u) {memset(dep, 0x3f, sizeof(dep)); dep[S] = 0;queue<int> q; q.push(S);while (!q.empty()) {int u = q.front(); q.pop();if (u == T) break;for (int i = head[u]; i != -1; i = nxt[i]) {if (fl[i] > 0 && dep[pnt[i]] == inf)dep[pnt[i]] = dep[u] + 1, q.push(pnt[i]);}}return dep[T] != inf;}int DFS(int u, int nf) {if (u == T || nf == 0) return nf;int flow = 0, tf;for (int &i = cur[u]; i != -1; i = nxt[i]) {int v = pnt[i];if (dep[v] != dep[u] + 1) continue;tf = DFS(v, min(nf, fl[i]));if (tf == 0) continue;flow += tf; nf -= tf;fl[i] -= tf; fl[i ^ 1] += tf;if (nf == 0) break;}return flow;}long long maxflow() {maxf = 0;while (BFS(S)) {memcpy(cur, head, sizeof(cur));maxf += DFS(S, inf);}return maxf;}};Dinic<205, 5005> G;int n, m, s, t;int main() {// scanf("%d%d%d%d",&n,&m,&s,&t);red(n); red(m); red(s); red(t);G.S = s, G.T = t;for (int i = 1; i <= m; ++i) {int u, v, c; red(u); red(v); red(c);// scanf("%d%d%d",&u,&v,&c);G.adde(u, v, c);}printf("%lld\n", G.maxflow());}
// 割边(桥)#include <bits/stdc++.h>using namespace std;const int N = 20010;const int M = 200010;int head[N], pnt[M], nxt[M], E, n, m;int dfn[N], low[N], tim;bool ecut[M];void adde(int u, int v) {E++; pnt[E] = v; nxt[E] = head[u]; head[u] = E;}void tarjan(int u, int in_edge) { // 考虑重边dfn[u] = low[u] = ++tim;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (!dfn[v]) {tarjan(v, i);low[u] = min(low[u], low[v]);if (dfn[u] < low[v]) ecut[i] = ecut[i ^ 1] = true;} else if (in_edge != (i ^ 1)) low[u] = min(low[u], dfn[v]);}}int main() {scanf("%d%d", &n, &m);E = 1;for (int i = 1; i <= m; ++i) {int u, v; scanf("%d%d", &u, &v);adde(u, v); adde(v, u);}for (int i = 1; i <= n; ++i) if (!dfn[i]) tarjan(i, 0);return 0;}
// 边双连通分量 & 缩点#include <bits/stdc++.h>using namespace std;const int N = 20010;const int M = 200010;int head[N], pnt[M], nxt[M], E, n, m;int headc[N], pntc[M], nxtc[M], Ec;int dfn[N], low[N], tim;bool ecut[M];void adde(int u, int v) {E++; pnt[E] = v; nxt[E] = head[u]; head[u] = E;}void addec(int u, int v) {Ec++; pntc[Ec] = v; nxtc[Ec] = headc[u]; headc[u] = Ec;}void tarjan(int u, int in_edge) { // 考虑重边dfn[u] = low[u] = ++tim;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (!dfn[v]) {tarjan(v, i);low[u] = min(low[u], low[v]);if (dfn[u] < low[v]) ecut[i] = ecut[i ^ 1] = true;} else if (in_edge != (i ^ 1)) low[u] = min(low[u], dfn[v]);}}int col[N], dcc;void dfs(int u) {col[u] = dcc;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (col[v] || ecut[i]) continue;dfs(v);}}int main() {scanf("%d%d", &n, &m);E = 1; // !!for (int i = 1; i <= m; ++i) {int u, v; scanf("%d%d", &u, &v);adde(u, v); adde(v, u);}// e-cutfor (int i = 1; i <= n; ++i) if (!dfn[i]) tarjan(i, 0);// e-DCC 断开割边,每个联通块即 e-DCCfor (int i = 1; i <= n; ++i) if (!col[i]) {++dcc, dfs(i);}// e-DCC 缩点for (int i = 2; i <= E; ++i) {int u = pnt[i], v = pnt[i ^ 1];if (col[u] == col[v]) continue;addec(col[u], col[v]);}return 0;}
// 最小割树#include <bits/stdc++.h>template<typename _Tp>inline void red(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}using namespace std;const int N = 505;const int M = 3005;const int inf = 0x3f3f3f3f;int n, m, q;struct networkflow {int head[N], pnt[M << 1], nxt[M << 1], fl[M << 1], E;int dep[N], cur[N], maxf;void adde(int u, int v, int f) {E++; pnt[E] = v; fl[E] = f; nxt[E] = head[u]; head[u] = E;E++; pnt[E] = u; fl[E] = 0; nxt[E] = head[v]; head[v] = E;}void init() {memset(head, -1, sizeof(head));E = -1;}void reset() { for (int i = 0; i < E; i += 2) fl[i] += fl[i + 1], fl[i + 1] = 0;}bool BFS(int S, int T) {memset(dep, 0x3f, sizeof(dep));dep[S] = 0; queue<int> q; q.push(S);while (!q.empty()) {int u = q.front(); q.pop();for (int i = head[u]; i != -1; i = nxt[i]) {int v = pnt[i];if (fl[i] > 0 && dep[v] == inf) {dep[v] = dep[u] + 1; q.push(v);}}}return dep[T] < inf;}int DFS(int u, int T, int nf) {if (u == T || nf == 0) return nf;int flow = 0, tf;for (int &i = cur[u]; i != -1; i = nxt[i]) {int v = pnt[i];if (dep[v] == dep[u] + 1) {tf = DFS(v, T, min(nf, fl[i]));flow += tf; nf -= tf;fl[i] -= tf; fl[i ^ 1] += tf;if (nf == 0) break;}}return flow;}void Dinic(int S, int T) {maxf = 0;while (BFS(S, T)) {memcpy(cur, head, sizeof(head));maxf += DFS(S, T, inf);}}} G;int t[N], head[N], pnt[N << 1], nxt[N << 1], wth[N << 1], E;int tl[N], tr[N];void adde(int u, int v, int w) {// fprintf(stderr,"e : %d %d %d\n",u,v,w);E++; pnt[E] = v; wth[E] = w; nxt[E] = head[u]; head[u] = E;}void Build(int l, int r) {if (l == r) return ;G.reset(); G.Dinic(t[l], t[r]);adde(t[l], t[r], G.maxf); adde(t[r], t[l], G.maxf);int cl = 0, cr = 0;for (int i = l; i <= r; ++i) {if (G.dep[t[i]] == inf) tr[cr++] = t[i];else tl[cl++] = t[i];}for (int i = 0; i < cl; ++i) t[l + i] = tl[i];for (int i = 0; i < cr; ++i) t[l + cl + i] = tr[i];Build(l, l + cl - 1); Build(l + cl, l + cl + cr - 1);}int fa[10][N], mn[10][N], dep[N];bool vis[N];void Prework(int u) {vis[u] = 1;for (int i = 1; i < 10; ++i) {fa[i][u] = fa[i - 1][fa[i - 1][u]];if (fa[i][u] == 0) break;mn[i][u] = min(mn[i - 1][u], mn[i - 1][fa[i - 1][u]]);}for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (v == fa[0][u]) continue;fa[0][v] = u; mn[0][v] = wth[i]; dep[v] = dep[u] + 1;Prework(v);}}int Query(int u, int v) {if (dep[u] < dep[v]) swap(u, v);int d = dep[u] - dep[v], ret = inf;for (int i = 0; i < 10; ++i) if ((d >> i) & 1)ret = min(ret, mn[i][u]), u = fa[i][u];if (u == v) return ret;for (int i = 9; i >= 0; --i) if (fa[i][u] != fa[i][v])ret = min(ret, min(mn[i][u], mn[i][v])),u = fa[i][u], v = fa[i][v];return min(ret, min(mn[0][u], mn[0][v]));}int main() {red(n); red(m);G.init();for (int i = 1; i <= m; ++i) {int u, v, w; red(u); red(v); red(w);G.adde(u, v, w); G.adde(v, u, w);}for (int i = 1; i <= n; ++i) t[i] = i;Build(1, n);Prework(1);red(q);while (q--) {int u, v; red(u); red(v);printf("%d\n", Query(u, v));}}
// 二分图最大匹配 匈牙利算法#include <bits/stdc++.h>using namespace std;const int N = 505;vector<int> e[N];int mx[N], my[N], n, m, E;bool vis[N];bool find(int x) {for (auto y : e[x]) if (!vis[y]) {vis[y] = 1;if (my[y] == 0 || find(my[y])) {my[y] = x, mx[x] = y;return true;}}return false;}int march(){int cnt = 0;memset(my, 0, sizeof(my));memset(mx, 0, sizeof(mx));for (int i = 1; i <= n; ++i) {memset(vis, 0, sizeof(vis));cnt += find(i);}return cnt;}int main() {scanf("%d%d%d", &n, &m, &E);for (int i = 1; i <= E; ++i) {int u, v; scanf("%d%d", &u, &v);e[u].push_back(v);}printf("%d\n", march());}
#include <bits/stdc++.h>#define fi first#define se secondtemplate<typename _Tp>inline void red(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}template<typename _Tp> bool umax(_Tp &x, _Tp y) {return (x < y) ? (x = y, true) : (false);}template<typename _Tp> bool umin(_Tp &x, _Tp y) {return (x > y) ? (x = y, true) : (false);}using namespace std;typedef long long ll;typedef pair<int, int> P;const int inf = 0x3f3f3f3f;int n, m, s, t;struct networkflow {static const int N = 5010, M = 100010;int head[N], pnt[M], fl[M], nxt[M], cst[M], pre[N], lst[N], E = -1;int dis[N], h[N]; bool vis[N];int minc, maxf, n;void init(int _n) {memset(head, -1, sizeof(head)); E = -1; n = _n;}void adde(int u, int v, int f, int c) {++E; pnt[E] = v; nxt[E] = head[u]; head[u] = E; fl[E] = f; cst[E] = c;++E; pnt[E] = u; nxt[E] = head[v]; head[v] = E; fl[E] = 0; cst[E] = -c;}bool SPFA(int S, int T) {memset(dis, 0x3f, sizeof(dis));memset(vis, 0, sizeof(vis));dis[S] = 0; vis[S] = 1; queue<int> q; q.push(S);while (!q.empty()) {int u = q.front(); q.pop();vis[u] = 0;for (int i = head[u]; i != -1; i = nxt[i]) {int v = pnt[i];if (fl[i] > 0 && dis[u] + cst[i] < dis[v]) {dis[v] = dis[u] + cst[i]; pre[v] = u; lst[v] = i;if (!vis[v]) q.push(v), vis[v] = 1;}}}return dis[T] < inf;}void work(int S, int T) {for (int i = 0; i <= n; ++i) h[i] += dis[i];int flow = inf;for (int u = T; u != S; u = pre[u]) flow = min(flow, fl[lst[u]]);maxf += flow; minc += flow * h[T];for (int u = T; u != S; u = pre[u]) {fl[lst[u]] -= flow;fl[lst[u] ^ 1] += flow;}}bool Dij(int S, int T) {priority_queue<P, vector<P>, greater<P> > q;memset(dis, 0x3f, sizeof(dis));memset(vis, 0, sizeof(vis));dis[S] = 0; q.push({0, S});while (!q.empty()) {int u = q.top().se; q.pop();if (vis[u]) continue; vis[u] = 1;for (int i = head[u]; i != -1; i = nxt[i]) {int v = pnt[i];if (fl[i] > 0 && dis[v] > dis[u] + cst[i] + h[u] - h[v]) {dis[v] = dis[u] + cst[i] + h[u] - h[v];pre[v] = u; lst[v] = i;q.push({dis[v], v});}}}return dis[T] < inf;}void MFMC(int S, int T) {minc = maxf = 0;memset(h, 0, sizeof(h));if (SPFA(S, T)) work(S, T);else return ;while (Dij(S, T)) work(S, T);}} G;int main() {red(n); red(m); red(s); red(t);G.init(n);for (int i = 1; i <= m; ++i) {int a, b, c, d; red(a); red(b); red(c); red(d);G.adde(a, b, c, d);}G.MFMC(s, t);printf("%d %d\n", G.maxf, G.minc);return 0;}
#include <bits/stdc++.h>using namespace std;template<size_t N, size_t M>struct SPFA_Dinic {const int inf = 0x3f3f3f3f;int fl[M << 1], cst[M << 1], pnt[M << 1], nxt[M << 1], cur[N], head[N], dis[N], E, S, T;bool vis[N];int maxf, minc;SPFA_Dinic() {memset(head, -1, sizeof(head)); E = -1;}void adde(int u, int v, int c, int w) { // (u,v) c容量限制,w单位费用E++; pnt[E] = v; fl[E] = c; cst[E] = w; nxt[E] = head[u]; head[u] = E;E++; pnt[E] = u; fl[E] = 0; cst[E] = -w; nxt[E] = head[v]; head[v] = E;}bool SPFA() {memset(dis, 0x3f, sizeof(dis));queue<int> q; q.push(S);dis[S] = 0; vis[S] = 1;while (!q.empty()) {int u = q.front(); q.pop(); vis[u] = 0;for (int i = head[u]; i != -1; i = nxt[i]) {int v = pnt[i];if (fl[i] > 0 && dis[v] > dis[u] + cst[i]) {dis[v] = dis[u] + cst[i];if (!vis[v]) q.push(v), vis[v] = 1;}}}return dis[T] != inf;}int DFS(int u, int nf) {if (u == T || nf == 0) return nf;int flow = 0, tf; vis[u] = 1;for (int &i = cur[u]; i != -1; i = nxt[i]) {int v = pnt[i];if (!vis[v] && fl[i] && dis[v] == dis[u] + cst[i]) {tf = DFS(v, min(nf, fl[i]));if (tf) {flow += tf; nf -= tf; fl[i] -= tf; fl[i ^ 1] += tf; minc += tf * cst[i];}}if (nf == 0) break;}vis[u] = 0;return flow;}void MFMC() {maxf = minc = 0;int cnt = 0;while (SPFA()) {memcpy(cur, head, sizeof(cur));maxf += DFS(S, inf);}}};SPFA_Dinic<5005, 50005> G;int n, m, s, t;int main() {scanf("%d%d%d%d", &n, &m, &s, &t);G.S = s, G.T = t;for (int i = 1; i <= m; ++i) {int u, v, c, w;scanf("%d%d%d%d", &u, &v, &c, &w);G.adde(u, v, c, w);}G.MFMC();printf("%d %d\n", G.maxf, G.minc);return 0;}
#include <bits/stdc++.h>template<typename _Tp>inline void red(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}using namespace std;const int inf = 0x3f3f3f3f;int n, m, s, t;struct networkflow {static const int N = 5010, M = 100010;int head[N], pnt[M], fl[M], nxt[M], cst[M], pre[N], lst[N], E = -1;int dis[N]; bool vis[N];int minc, maxf;void init() {memset(head, -1, sizeof(head)); E = -1;}void adde(int u, int v, int f, int c) {++E; pnt[E] = v; nxt[E] = head[u]; head[u] = E; fl[E] = f; cst[E] = c;++E; pnt[E] = u; nxt[E] = head[v]; head[v] = E; fl[E] = 0; cst[E] = -c;}bool SPFA(int S, int T) {memset(dis, 0x3f, sizeof(dis));memset(vis, 0, sizeof(vis));dis[S] = 0; vis[S] = 1; queue<int> q; q.push(S);while (!q.empty()) {int u = q.front(); q.pop();vis[u] = 0;for (int i = head[u]; i != -1; i = nxt[i]) {int v = pnt[i];if (fl[i] > 0 && dis[u] + cst[i] < dis[v]) {dis[v] = dis[u] + cst[i]; pre[v] = u; lst[v] = i;if (!vis[v]) q.push(v), vis[v] = 1;}}}return dis[T] < inf;}void work(int S, int T) {int flow = inf;for (int u = T; u != S; u = pre[u]) flow = min(flow, fl[lst[u]]);maxf += flow; minc += flow * dis[T];for (int u = T; u != S; u = pre[u]) {fl[lst[u]] -= flow;fl[lst[u] ^ 1] += flow;}}void MFMC(int S, int T) {minc = maxf = 0;while (SPFA(S, T)) work(S, T);}} G;int main() {red(n); red(m); red(s); red(t);G.init();for (int i = 1; i <= m; ++i) {int a, b, c, d; red(a); red(b); red(c); red(d);G.adde(a, b, c, d);}G.MFMC(s, t);printf("%d %d\n", G.maxf, G.minc);}
// Prufer 序列#include <bits/stdc++.h>template <typename Tp>inline void read(Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}using namespace std;const int N = 5000010;int n, type, a[N];long long ans = 0;namespace prufer {int p[N], f[N], deg[N];void encode(int *f, int n) { // father -> pruferfor (int i = 1; i <= n; ++i) deg[i] = 0;for (int i = 1; i < n; ++i) ++deg[f[i]];for (int i = 1, j = 1; i <= n - 2; ++i, ++j) {while (deg[j]) ++j; p[i] = f[j];while (i <= n - 2 && --deg[p[i]] == 0 && p[i] < j) p[i + 1] = f[p[i]], ++i;}for (int i = 1; i <= n - 2; ++i) ans ^= 1ll * i * p[i];}void decode(int *p, int n) { // prufer -> fatherfor (int i = 1; i <= n; ++i) deg[i] = 0;for (int i = 1; i <= n - 2; ++i) ++deg[p[i]]; p[n - 1] = n;for (int i = 1, j = 1; i < n; ++i, ++j) {while (deg[j]) ++j; f[j] = p[i];while (i < n && --deg[p[i]] == 0 && p[i] < j) f[p[i]] = p[i + 1], ++i;}for (int i = 1; i <= n - 1; ++i) ans ^= 1ll * i * f[i];}}int main() {read(n); read(type);for (int i = 1; i <= n - type; ++i) read(a[i]);if (type == 1) prufer::encode(a, n);else prufer::decode(a, n);printf("%lld\n", ans);return 0;}
// 强连通分量#include <bits/stdc++.h>using namespace std;const int N = 10010;const int M = 200010;int head[N], pnt[M], nxt[M], E, n, m;int dfn[N], low[N], tim, sta[N], top, scc[N], cnt;void adde(int u, int v) {E++; pnt[E] = v; nxt[E] = head[u]; head[u] = E;}void tarjan(int u) {dfn[u] = low[u] = ++tim;sta[++top] = u;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (!dfn[v]) {tarjan(v);low[u] = min(low[u], low[v]);} else if (!scc[v]) low[u] = min(low[u], dfn[v]);}if (dfn[u] == low[u]) {++cnt;do {scc[sta[top]] = cnt;} while (sta[top--] != u);}}int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= m; ++i) {int u, v; scanf("%d%d", &u, &v);adde(u, v); adde(v, u);}for (int i = 1; i <= n; ++i) if (!dfn[i]) top = 0, tarjan(i);return 0;}
// 最小斯坦纳树// https://www.luogu.com.cn/problem/P6192#include <bits/stdc++.h>template <typename Tp>inline void read(Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') { if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}template <typename Tp, typename... Args>void read(Tp &t, Args &...args) { read(t); read(args...); }using namespace std;typedef long long ll;const int N = 105;const int M = 1010;const int inf = 0x3f3f3f3f;int head[N], pnt[M], nxt[M], wth[M], E;int n, m, k, id[N], _id, ful;int dp[1 << 10][N];void adde(int u, int v, int w) {E++; pnt[E] = v; wth[E] = w; nxt[E] = head[u]; head[u] = E;}struct dat {int u, d;bool operator<(const dat a) const {return d > a.d;}};bool vis[N];priority_queue<dat> Q;void dijk(int S) {memset(vis, 0, sizeof(vis));while (!Q.empty()) {int u = Q.top().u; Q.pop();if (vis[u]) continue;vis[u] = 1;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (!vis[v] && dp[S][v] > dp[S][u] + wth[i]) {dp[S][v] = dp[S][u] + wth[i];Q.push(dat{v, dp[S][v]});}}}}int main() {read(n, m, k);for (int i = 1; i <= m; ++i) {int u, v, w; read(u, v, w);adde(u, v, w); adde(v, u, w);}memset(id, -1, sizeof(id));for (int i = 1; i <= k; ++i) {int x; read(x); id[x] = _id++;}ful = (1 << k) - 1;memset(dp, 0x3f, sizeof(dp));for (int i = 1; i <= n; ++i) if (id[i] != -1)dp[1 << id[i]][i] = 0;for (int S = 1; S <= ful; ++S) {for (int i = 1; i <= n; ++i) {for (int sub = (S - 1) & S; sub; sub = (sub - 1) & S)dp[S][i] = min(dp[S][i], dp[sub][i] + dp[S ^ sub][i]);if (dp[S][i] < inf) {Q.push(dat{i, dp[S][i]});}}dijk(S);}int ans = inf;for (int i = 1; i <= n; ++i)ans = min(ans, dp[ful][i]);printf("%d\n", ans);return 0;}
// 割点(割顶)#include <bits/stdc++.h>using namespace std;const int N = 20010;const int M = 200010;int head[N], pnt[M], nxt[M], E, n, m;int dfn[N], low[N], tim, root;bool vcut[N];void adde(int u, int v) {E++; pnt[E] = v; nxt[E] = head[u]; head[u] = E;}void tarjan(int u) {dfn[u] = low[u] = ++tim;int child = 0;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (!dfn[v]) {tarjan(v); low[u] = min(low[u], low[v]);if (dfn[u] <= low[v]) {++child;if (u != root || child >= 2) vcut[u] = true;}} else low[u] = min(low[u], dfn[v]);}}int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= m; ++i) {int u, v; scanf("%d%d", &u, &v);adde(u, v); adde(v, u);}for (int i = 1; i <= n; ++i) if (!dfn[i]) root = i, tarjan(i);return 0;}
// 点双连通分量 & 缩点#include <bits/stdc++.h>using namespace std;const int N = 20010;const int M = 200010;int head[N], pnt[M], nxt[M], E, n, m;int headc[N], pntc[M], nxtc[M], Ec;int dfn[N], low[N], tim, root, sta[N], top;bool vcut[N];vector<int> dcc[N]; int col[N], cnt;int tot, new_id[N];void adde(int u, int v) {E++; pnt[E] = v; nxt[E] = head[u]; head[u] = E;}void addec(int u, int v) {Ec++; pntc[Ec] = v; nxtc[Ec] = headc[u]; headc[u] = Ec;}void tarjan(int u) {dfn[u] = low[u] = ++tim;sta[++top] = u;if (u == root && head[u] == 0) { // 孤立点dcc[++cnt].push_back(u); return;}int child = 0;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (!dfn[v]) {tarjan(v); low[u] = min(low[u], low[v]);if (dfn[u] <= low[v]) {++child;if (u != root || child >= 2) vcut[u] = true;++cnt;while (1) {dcc[cnt].push_back(sta[top]);if (sta[top--] == v) break;}dcc[cnt].push_back(u);}} else low[u] = min(low[u], dfn[v]);}}int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= m; ++i) {int u, v; scanf("%d%d", &u, &v);adde(u, v); adde(v, u);}for (int i = 1; i <= n; ++i) if (!dfn[i]) root = i, top = 0, tarjan(i);// 割点可以属于多个 v-DCC,其它点只属于一个 v-DCC// 缩点: 割点重新编号,每个 v-DCC 向它包含的割点连边tot = cnt;for (int i = 1; i <= n; ++i) if (vcut[i]) new_id[i] = ++tot;for (int i = 1; i <= cnt; ++i) {for (auto &u : dcc[i]) {if (vcut[u]) {addec(i, new_id[u]);addec(new_id[u], i);} else col[u] = i;}}return 0;}
// 点分树 luogu-P6329#include <bits/stdc++.h>#define see(x) cerr<<#x<<"="<<x<<endl;#define _max(x,y) ((x>y)?x:y)#define _min(x,y) ((x<y)?x:y)using namespace std;typedef long long ll;template<typename _Tp>inline void red(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}const int N = 100010;const int M = 20;int head[N], pnt[N << 1], nxt[N << 1], E;int val[N], son[N], siz[N], dep[N], mxdep, size, root, n, m;int far[N], Dep[N], dist[M][N];struct trearr {vector<int> t; int n;void init(int sz) {t.resize(sz + 1, 0); n = sz;}void add(int x, int v) {for (; x <= n; x += x & -x) t[x] += v;}int sum(int x) {int r = 0; for (x = _min(x, n); x > 0; x -= x & -x) r += t[x]; return r;}} Dt[N], dt[N];trearr *ps[N];bool vis[N];void adde(int u, int v) { E++; pnt[E] = v; nxt[E] = head[u]; head[u] = E; }void getroot(int u, int f) {siz[u] = 1; son[u] = 0;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (v == f || vis[v]) continue;getroot(v, u);siz[u] += siz[v];son[u] = _max(son[u], siz[v]);}son[u] = _max(son[u], size - siz[u]);if (son[u] < son[root]) root = u;}void dfs(int u, int f, int S, int fr) {Dt[S].add(dep[u], val[u]); dt[fr].add(dep[u], val[u]);dist[Dep[S]][u] = dep[u];for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (v == f || vis[v]) continue;dfs(v, u, S, fr);}}void DFS(int u, int f, int d) {dep[u] = d; siz[u] = 1; mxdep = _max(mxdep, d);for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (v == f || vis[v]) continue;DFS(v, u, d + 1); siz[u] += siz[v];}}void vdiv(int u) {int mx = 0;vector<pair<int, int> > sons;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (vis[v]) continue;mxdep = 0; DFS(v, u, 1); mx = _max(mx, mxdep);size = siz[v]; root = 0; getroot(v, u);sons.push_back(make_pair(v, root)); far[root] = u;dt[root].init(mxdep);}Dt[u].init(mx);for (int i = 0; i < sons.size(); ++i)dfs(sons[i].first, u, u, sons[i].second);vis[u] = 1;for (int i = 0; i < sons.size(); ++i) {Dep[sons[i].second] = Dep[u] + 1;vdiv(sons[i].second);}}int ask(int x, int K) {int ret = 0, fr = -1;for (int u = x; u; u = far[u]) {int d = K - dist[Dep[u]][x];if (d > 0) {ret += Dt[u].sum(d);if (fr != -1)ret -= dt[fr].sum(d);}if (d >= 0) ret += val[u];fr = u;}return ret;}void modify(int x, int vl) {int fr = x;for (int u = far[x]; u; u = far[u]) {int d = dist[Dep[u]][x];Dt[u].add(d, -val[x]); dt[fr].add(d, -val[x]);Dt[u].add(d, vl); dt[fr].add(d, vl);fr = u;}val[x] = vl;}int main() {red(n); red(m);for (int i = 1; i <= n; ++i) red(val[i]);for (int i = 1; i < n; ++i) {int u, v; red(u); red(v);adde(u, v); adde(v, u);}size = n; son[root = 0] = n;getroot(1, 0);vdiv(root);int lst = 0;while (m--) {int op, x, y; red(op); red(x); red(y);x ^= lst; y ^= lst;if (op == 0) {lst = ask(x, y);printf("%d\n", lst);} elsemodify(x, y);}return 0;}
/*luogu - P2495 [SDOI2011]消耗战虚树板子,建树看 build()Oi-wiki(虚树) --> https://oi-wiki.org/graph/virtual-tree/*/#include <bits/stdc++.h>using namespace std;template <typename T>inline void red(T &x) {x = 0; bool f = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') f ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (T)(ch ^ 48), ch = getchar();if (f) x = -x;}const int N = 300000;const int inf = 0x3f3f3f3f;typedef long long ll;int head[N], pnt[N << 1], nxt[N << 1], wth[N << 1], E;int dfn[N], tim, h[N], K;int n, Q, fa[N], deg[N], W[N], ty[N];ll Dp[N];namespace LCA {int siz[N], son[N], top[N], fa[N], dep[N];void dfs1(int u, int f, int d) {fa[u] = f; dep[u] = d; siz[u] = 1;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (v == f) continue;dfs1(v, u, d + 1); siz[u] += siz[v];if (siz[son[u]] < siz[v]) son[u] = v;}}void dfs2(int u, int topf) {top[u] = topf;if (son[u]) dfs2(son[u], topf);for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (v == son[u] || v == fa[u]) continue;dfs2(v, v);}}int lca(int u, int v) {int fu = top[u], fv = top[v];while (fu != fv) {if (dep[fu] < dep[fv]) swap(fu, fv), swap(u, v);u = fa[fu]; fu = top[u];}return (dep[u] < dep[v]) ? u : v;}}using LCA::lca;void adde(int u, int v, int w) {E++; pnt[E] = v; nxt[E] = head[u]; wth[E] = w; head[u] = E;}bool cmp(int x, int y) { return dfn[x] < dfn[y];}void dfs(int u, int f) {dfn[u] = ++tim;for (int i = head[u]; i; i = nxt[i]) {int v = pnt[i];if (v == f) continue;W[v] = min(W[u], wth[i]);dfs(v, u);}}// begin : build virtual treeint st[N], top, b[N], tot; // b[1:tot] are the nodes in virtual treevoid build() {sort(h + 1, h + K + 1, cmp);st[top = 1] = 1; deg[1] = fa[1] = 0; b[tot = 1] = 1;for (int i = 1; i <= K; ++i) {if (h[i] == 1) continue;int lc = lca(h[i], st[top]);if (lc != st[top]) {while (dfn[lc] < dfn[st[top - 1]]) {fa[st[top]] = st[top - 1];++deg[st[top - 1]];top--;}if (dfn[lc] > dfn[st[top - 1]]) {fa[st[top]] = lc; deg[lc] = 1;fa[lc] = 0, st[top] = lc; b[++tot] = lc;} else {fa[st[top--]] = lc; ++deg[lc];}}st[++top] = h[i]; b[++tot] = h[i];deg[h[i]] = fa[h[i]] = 0;}for (int i = 2; i <= top; ++i) fa[st[i]] = st[i - 1], ++deg[st[i - 1]];}// end buildll solve() {queue<int> q;for (int i = 1; i <= tot; ++i) {Dp[b[i]] = 0;if (deg[b[i]] == 0) q.push(b[i]);}while (!q.empty()) {int u = q.front(); q.pop();if (u == 1) break;if (ty[u]) Dp[fa[u]] += W[u];else Dp[fa[u]] += min((ll)W[u], Dp[u]);--deg[fa[u]];if (deg[fa[u]] == 0) q.push(fa[u]);}return Dp[1];}int main() {red(n);for (int i = 1; i < n; ++i) {int u, v, w; red(u); red(v); red(w);adde(u, v, w); adde(v, u, w);}W[1] = inf;dfs(1, 0);LCA::dfs1(1, 0, 0); LCA::dfs2(1, 1);red(Q);while (Q--) {red(K);for (int i = 1; i <= K; ++i) red(h[i]), ty[h[i]] = 1;build();ll ans = solve();printf("%lld\n", ans);for (int i = 1; i <= K; ++i) ty[h[i]] = 0;}}
// P3812 【模板】线性基#include <bits/stdc++.h>using namespace std;typedef long long ll;const int B = 52;ll d[B], x;int tot, n;void insert(ll x) {for (int i = B - 1; i >= 0; --i) if ((x >> i) & 1) {if (d[i] == 0) {d[i] = x, ++tot; return ;}x ^= d[i];}}ll getmax() {ll ret = 0;for (int i = B - 1; i >= 0; --i) if ((ret ^ d[i]) > ret) ret ^= d[i];return ret;}ll getmin() {if (tot < n) return 0;for (int i = 0; i < B; ++i) if (d[i] != 0) return d[i];return -1;}void work() {for (int i = 1; i < B; ++i)for (int j = 0; j < i; ++j)if ((d[i] >> j) & 1) d[i] ^= d[j];}ll getkth(ll k) {if (k == 1 && tot < n) return 0;if (tot < n) --k;work(); ll ret = 0;for (int i = 0; i < B; ++i, k >>= 1) if (d[i] && (k & 1)) ret ^= d[i];return ret;}int main() {cin >> n;for (int i = 1; i <= n; ++i) {cin >> x;insert(x);}printf("%lld\n", getmax());}
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N = 20;ll a[N], b[N]; int n;ll exgcd(ll a, ll b, ll &x, ll &y) {if (!b) {x = 1, y = 0; return a;}ll d = exgcd(b, a % b, x, y);swap(x, y); y -= a / b * x;return d;}ll inv(ll a, ll b) {ll x, y; exgcd(a, b, x, y);return (x % b + b) % b;}// x=ai (mod mi) gcd(m1,m2....mn)=1ll CRT(int n, ll a[], ll m[]) {ll M = 1, x = 0;for (int i = 1; i <= n; i++) M *= m[i];for (int i = 1; i <= n; i++)x = (x + (M / m[i]) * inv(M / m[i], m[i]) % M * a[i] % M) % M;return x;}int main() {scanf("%d", &n);for (int i = 1; i <= n; i++) scanf("%lld%lld", &a[i], &b[i]);ll ans = CRT(n, b, a);printf("%lld\n", ans);}
#include <bits/stdc++.h>using namespace std;typedef long long ll;ll gcd(ll a, ll b) {return !b ? a : gcd(b, a % b);}ll exgcd(ll a, ll b, ll &x, ll &y) {if (!b) {x = 1, y = 0; return a;}ll d = exgcd(b, a % b, x, y);swap(x, y); y -= a / b * x;return d;}ll inv(ll a, ll b) {ll x, y; exgcd(a, b, x, y);return (x % b + b) % b;}ll BSGS(ll a, ll n, ll p) {ll ans = p, t = ceil(sqrt(p)), dt = 1;map<ll, ll> hash;for (ll B = 1; B <= t; B++) dt = (dt * a) % p, hash[(dt * n) % p] = B;for (ll A = 1, num = dt; A <= t;A++, num = (num * dt) % p) if (hash.find(num) != hash.end()) ans = min(ans, A * t - hash[num]);return ans;}//a^x=n (mod p)ll EXBSGS(ll a, ll n, ll p) {int k = 0; ll d, ad = 1;while ((d = gcd(a, p)) != 1) {if (n % d) return -1;n /= d, p /= d; ad *= a / d; ad %= p; k++;}n = (n * inv(ad, p)) % p;ll res = BSGS(a, n, p);if (res == p) return -1;return res + k;}ll a, p, n;int main() {while (cin >> a >> p >> n) {if (a == 0 && p == 0 && n == 0) break;ll ans = EXBSGS(a, n, p);if (ans == -1) printf("No Solution\n");else printf("%lld\n", ans);}}
#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N = 100010;ll a[N], b[N]; int n;ll mul(ll a, ll b, ll mod) {ll r = 0;a = (a % mod + mod) % mod;b = (b % mod + mod) % mod;while (b) {if (b & 1) r = (r + a) % mod;a = (a << 1) % mod; b >>= 1;} return r;}ll gcd(ll a, ll b) {return !b ? a : gcd(b, a % b);}ll exgcd(ll a, ll b, ll &x, ll &y) {if (!b) {x = 1, y = 0; return a;}ll d = exgcd(b, a % b, x, y);swap(x, y); y -= a / b * x;return d;}// x=ai (mod mi)ll EXCRT(int n, ll a[], ll m[]) {for (int i = 2; i <= n; i++) {ll d = gcd(m[i - 1], m[i]), x, y;if ((a[i] - a[i - 1]) % d != 0) return -1; // 无解exgcd(m[i - 1] / d, m[i] / d, x, y);m[i] = m[i] / gcd(m[i], m[i - 1]) * m[i - 1];a[i] = (a[i - 1] + mul(mul((a[i] - a[i - 1]) / d, x, m[i]), m[i - 1], m[i])) % m[i];a[i] = (a[i] + m[i]) % m[i];}return a[n];}int main() {scanf("%d", &n);for (int i = 1; i <= n; i++)scanf("%lld%lld", &a[i], &b[i]);ll ans = EXCRT(n, b, a);printf("%lld\n", ans);}
#include <bits/stdc++.h>using namespace std;typedef long long ll;ll mul(ll a, ll b, ll p) {ll l = ((b >> 30) % p * (1ll << 30) % p) % p;ll r = (b & ((1ll << 30) - 1ll)) % p;return ((l * a) % p + (r * a) % p) % p;}ll fpow(ll a, ll b, ll p) {ll r = 1ll;while (b) {if (b & 1) r = mul(r, a, p);a = mul(a, a, p);b >>= 1;}return r;}ll exgcd(ll a, ll b, ll &x, ll &y) {if (!b) {x = 1ll, y = 0; return a;}ll d = exgcd(b, a % b, x, y); swap(x, y);y -= (a / b) * x; return d;}ll inv(ll a, ll p) {ll iv, k;exgcd(a, p, iv, k);return (iv % p + p) % p;}// calc (n!/p^c) mod p^k which gcd(n!/p^c,p^k)=1ll fact(ll n, ll p, ll pk) {if (!n) return 1ll;ll ret = 1ll;for (ll i = 1ll; i <= pk; i++) {if (i % p) ret = ret * i % pk;}ret = fpow(ret, n / pk, pk);for (ll i = 1ll; i <= n % pk; i++) {if (i % p) ret = ret * i % pk;}return ret * fact(n / p, p, pk) % pk;}ll C(ll n, ll m, ll p, ll pk) {if (n < m) return 0;ll f1 = fact(n, p, pk), f2 = inv(fact(m, p, pk), pk), f3 = inv(fact(n - m, p, pk), pk);ll cnt = 0;for (ll i = n; i; i /= p) cnt += i / p;for (ll i = m; i; i /= p) cnt -= i / p;for (ll i = n - m; i; i /= p) cnt -= i / p;return f1 * f2 % pk * f3 % pk * fpow(p, cnt, pk) % pk;}ll CRT(int n, ll a[], ll m[]) {ll M = 1, ret = 0;for (int i = 1; i <= n; i++) M *= m[i];for (int i = 1; i <= n; i++)ret = (ret + a[i] * (M / m[i]) % M * inv(M / m[i], m[i])) % M;return (ret % M + M) % M;}ll exlucas(ll n, ll m, ll p) {ll pk[24], c[24]; int tot = 0;for (ll i = 2ll; i <= p / i; i++) {if (p % i == 0) {pk[++tot] = 1ll;while (p % i == 0) p /= i, pk[tot] *= i;c[tot] = C(n, m, i, pk[tot]);}}if (p > 1) pk[++tot] = p, c[tot] = C(n, m, p, p);return CRT(tot, c, pk);}int main() {ll n, m, p;cin >> n >> m >> p;cout << exlucas(n, m, p) << endl;}
#include <bits/stdc++.h>using namespace std;const int N = 105;double a[N][N];int n;void init() {scanf("%d", &n);for (int i = 1; i <= n; i++)for (int j = 1; j <= n + 1; j++)scanf("%lf", &a[i][j]);}void solve() {for (int j = 1; j <= n; j++) {int mxp = j;for (int i = j + 1; i <= n; i++)if (fabs(a[i][j]) > fabs(a[mxp][j])) mxp = i;for (int i = 1; i <= n + 1; i++)swap(a[j][i], a[mxp][i]);if (a[j][j] == 0) {printf("No Solution\n");return ;}for (int i = 1; i <= n; i++) {if (i == j) continue;double tmp = a[i][j] / a[j][j];for (int k = 1; k <= n + 1; k++)a[i][k] -= a[j][k] * tmp;}}for (int i = 1; i <= n; i++)printf("%.2lf\n", a[i][n + 1] / a[i][i]);}int main() {init();solve();return 0;}
// 原根#include <bits/stdc++.h>using namespace std;const int N = 1000010;int p[N], tot, phi[N]; // p[] 素数,phi[] 欧拉函数bool v[N], has[N]; // v[] 是否是素数, is[] 是否有原根int Ts;typedef long long ll;ll fpow(ll a, ll b, ll p) {ll r = 1; for (; b; b >>= 1, a = (a * a) % p) if (b & 1) r = (r * a) % p; return r;}int gcd(int a, int b) {return !b ? a : gcd(b, a % b);}void init(int n) { // 预处理欧拉函数,素数,及那些数有原根phi[1] = 1;for (int i = 2; i <= n; ++i) {if (!v[i]) p[++tot] = i, phi[i] = i - 1;for (int j = 1; j <= tot && p[j]*i <= n; ++j) {v[p[j]*i] = 1;if (i % p[j] == 0) {phi[i * p[j]] = phi[i] * p[j];break;}phi[i * p[j]] = phi[i] * (p[j] - 1);}}has[2] = has[4] = 1;for (int i = 2; i <= tot; ++i) for (ll j = p[i]; j <= n; j *= p[i]) has[j] = 1, (j * 2 <= n)&& (has[j * 2] = 1);}void devide(int x, vector<int> &ret) { // 分解质因数ret.clear();for (int i = 1; 1ll * p[i]*p[i] <= x; ++i) if (x % p[i] == 0) {ret.push_back(p[i]);while (x % p[i] == 0) x /= p[i];}if (x > 1) ret.push_back(x);}bool hasroot(int n) { // 判断一个数是否有原根if (n == 2 || n == 4) return 1;if (n % 2 == 0) n /= 2;if (n % 2 == 0) return 0;for (int i = 2; 1ll * p[i]*p[i] <= n; ++i) if (n % p[i] == 0) {while (n % p[i] == 0) n /= p[i];return (n == 1);}return 1;}void Getroot(int m, vector<int> &res) {res.clear();if (!has[m]) return ;vector<int> factor;devide(phi[m], factor);int g = 1, mphi = phi[m];while (true) {bool fg = 1;if (gcd(g, m) != 1) fg = 0; //i不存在模n的阶else for (int i = 0; i < (int)factor.size(); ++i) {if (fpow(g, mphi / factor[i], m) == 1ll) {fg = 0; break;}}if (fg) break;++g;}ll pw = 1;for (int s = 1; (int)res.size() < phi[mphi]; ++s) {pw = (pw * g) % m;if (gcd(s, mphi) == 1) res.push_back(pw);}sort(res.begin(), res.end());}int main() {init(1e6);scanf("%d", &Ts);while (Ts--) {int n, d; // 找 n 的所有原根scanf("%d%d", &n, &d);vector<int> ans;Getroot(n, ans);printf("%d\n", (int)ans.size());for (int i = d - 1; i < (int)ans.size(); i += d) printf("%d ", ans[i]);printf("\n");}}
// 数值积分,自适应辛普森法#include <cmath>#include <cstdio>using namespace std;typedef double db;// 要计算的函数db f(db x) {return x * x * x;}// 辛普森公式 = (r - l) / 6 * (f(l) + f(r) + 4f((l + r) / 2))db simpon(db l, db r) {db mid = (l + r) / 2.0;return (r - l) * (f(l) + f(r) + f(mid) * 4.0) / 6.0;}db simpon(db l, db r, db eps, db ans, int step) {db mid = (l + r) / 2.0;db fl = simpon(l, mid), fr = simpon(mid, r);if (fabs(fl + fr - ans) <= 15.0 * eps && step < 0) return fl + fr + (fl + fr - ans) / 15.0;return simpon(l, mid, eps / 2.0, fl, step - 1) + simpon(mid, r, eps / 2.0, fr, step - 1);}db calc(db l, db r, db eps) {return simpon(l, r, eps, simpon(l, r), 12);}
// 第一类斯特林数·行#include <algorithm>#include <cstdio>#include <iostream>#include <cstring>#define clr(f,n) memset(f,0,sizeof(long long)*(n))#define cpy(f,g,n) memcpy(f,g,sizeof(long long)*(n))#define _max(x,y) ((x>y)?x:y)#define _min(x,y) ((x<y)?x:y)#define MOD(x) ((x)<mod?(x):((x)%mod))using namespace std;typedef long long ll;template<typename _Tp>inline void red(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}template<typename _Tp> bool umax(_Tp &x, _Tp y) {return (x < y) ? (x = y, true) : (false);}template<typename _Tp> bool umin(_Tp &x, _Tp y) {return (x > y) ? (x = y, true) : (false);}const int N = (1 << 19);const int mod = 167772161;const int _G = 3;const int _iG = 55924054;int rev[N], rev_n;ll inv[N], ifac[N], fac[N];ll fpow(ll a, ll b = mod - 2) {ll r = 1;for (; b; b >>= 1, a = MOD(a * a)) if (b & 1) r = MOD(r * a);return r;}void prerev(int n) {if (rev_n == n) return ;for (int i = 0; i < n; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (n >> 1) : 0);rev_n = n;}void NTT(ll f[], int n, int fg) {prerev(n);for (int i = 0; i < n; ++i) if (i < rev[i]) swap(f[i], f[rev[i]]);for (int h = 2; h <= n; h <<= 1) {int len = h >> 1;ll Dt = fpow((fg == 1) ? _G : _iG, (mod - 1) / h), w;for (int j = 0; j < n; j += h) { // j<n !! not j<=nw = 1;for (int k = j; k < j + len; ++k) {ll tt = MOD(w * f[k + len]);f[k + len] = f[k] - tt; (f[k + len] < 0) &&(f[k + len] += mod);f[k] = f[k] + tt; (f[k] >= mod) &&(f[k] -= mod);w = MOD(w * Dt);}}}if (fg == -1) {ll invn = fpow(n, mod - 2);for (int i = 0; i < n; ++i) f[i] = MOD(f[i] * invn);}}ll S1[N];int n;// change f(x) to f(x+n)void change(ll f[], int n) {static ll g[N];int nn;for (nn = 1; nn < (2 * n + 2); nn <<= 1) ;clr(g, nn); clr(f + n + 1, nn - n - 1);for (int i = 0; i <= n; ++i) f[i] = MOD(f[i] * fac[i]);for (int i = 0, pw = 1; i <= n; ++i, pw = MOD((ll)pw * n)) g[n - i] = MOD((ll)pw * ifac[i]);NTT(f, nn, 1); NTT(g, nn, 1);for (int i = 0; i < nn; ++i) f[i] = MOD(f[i] * g[i]);NTT(f, nn, -1);for (int i = 0; i <= n; ++i)f[i] = MOD(f[i + n] * ifac[i]);clr(f + n + 1, nn - n - 1);}void GetS1(ll f[], int n) {static int stk[50], top;static ll g[N];top = 0;while (n) stk[++top] = n, n >>= 1;clr(f, n << 1); f[1] = 1;for (int tt = top - 1; tt >= 1; --tt) {int now = stk[tt], len = stk[tt + 1], nn;cpy(g, f, len + 1);change(g, len);for (nn = 1; nn < (len * 2 + 2); nn <<= 1) ;NTT(f, nn, 1); NTT(g, nn, 1);for (int i = 0; i < nn; ++i) f[i] = MOD(f[i] * g[i]);NTT(f, nn, -1);if ((len << 1) + 1 == now) {// * (x+now-1)for (int i = now; i >= 0; --i) {f[i + 1] = MOD(f[i + 1] + f[i]);f[i] = MOD(f[i] * (now - 1));}}}}int main() {red(n);fac[0] = fac[1] = inv[0] = inv[1] = ifac[0] = ifac[1] = 1;for (int i = 2; i <= n + 1; ++i) fac[i] = MOD(fac[i - 1] * i);for (int i = 2; i <= n + 1; ++i) inv[i] = MOD((mod - mod / i) * inv[mod % i]);for (int i = 2; i <= n + 1; ++i) ifac[i] = MOD(ifac[i - 1] * inv[i]);GetS1(S1, n);for (int i = 0; i <= n; ++i)printf("%lld ", S1[i]);printf("\n");return 0;}/*生活不止眼前的 OI还有 逻辑 与 并行*/
// 第二类斯特林数·行#include <algorithm>#include <cstdio>#include <iostream>#define _max(x,y) ((x>y)?x:y)#define _min(x,y) ((x<y)?x:y)#define MOD(x) ((x)<mod?(x):((x)%mod))using namespace std;typedef long long ll;template<typename _Tp>inline void red(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}template<typename _Tp> bool umax(_Tp &x, _Tp y) {return (x < y) ? (x = y, true) : (false);}template<typename _Tp> bool umin(_Tp &x, _Tp y) {return (x > y) ? (x = y, true) : (false);}const int N = (1 << 19);const int mod = 167772161;const int _G = 3;const int _iG = 55924054;int rev[N], rev_n;ll inv[N], ifac[N], fac[N];ll S2[N], f[N], g[N];ll fpow(ll a, ll b = mod - 2) {ll r = 1;for (; b; b >>= 1, a = MOD(a * a)) if (b & 1) r = MOD(r * a);return r;}void prerev(int n) {if (rev_n == n) return ;for (int i = 0; i < n; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (n >> 1) : 0);rev_n = n;}void NTT(ll f[], int n, int fg) {prerev(n);for (int i = 0; i < n; ++i) if (i < rev[i]) swap(f[i], f[rev[i]]);for (int h = 2; h <= n; h <<= 1) {int len = h >> 1;ll Dt = fpow((fg == 1) ? _G : _iG, (mod - 1) / h), w;for (int j = 0; j < n; j += h) { // j<n !! not j<=nw = 1;for (int k = j; k < j + len; ++k) {ll tt = MOD(w * f[k + len]);f[k + len] = f[k] - tt; (f[k + len] < 0) &&(f[k + len] += mod);f[k] = f[k] + tt; (f[k] >= mod) &&(f[k] -= mod);w = MOD(w * Dt);}}}if (fg == -1) {ll invn = fpow(n, mod - 2);for (int i = 0; i < n; ++i) f[i] = MOD(f[i] * invn);}}int n, k, nn;int main() {red(n);fac[0] = fac[1] = inv[0] = inv[1] = ifac[0] = ifac[1] = 1;for (int i = 2; i <= n; ++i) fac[i] = MOD(fac[i - 1] * i);for (int i = 2; i <= n; ++i) inv[i] = MOD((mod - mod / i) * inv[mod % i]);for (int i = 2; i <= n; ++i) ifac[i] = MOD(ifac[i - 1] * inv[i]);for (int k = 0; k <= n; ++k) {f[k] = ifac[k];if (k & 1) f[k] = MOD(mod - f[k]);g[k] = MOD(ifac[k] * fpow(k, n));}for (nn = 1; nn < (n * 2 + 2); nn <<= 1) ;NTT(f, nn, 1); NTT(g, nn, 1);for (int i = 0; i < nn; ++i) S2[i] = MOD(f[i] * g[i]);NTT(S2, nn, -1);for (int i = 0; i <= n; ++i) printf("%lld ", S2[i]);printf("\n");return 0;}
#include <windows.h>#include <cstdio>#include <string>#include <cstring>#include <ctime>using namespace std;string tmp;int st;void setclock() {st = clock();}int getclock() {return clock() - st;}int ifcpl = 1, test_times = 1e9;string comd = "-std=c++11 -Wall -O2";void PrintHelp() {printf("Uesge:\n");printf("\tchk <std.cpp> <test.cpp> <mker.cpp> [-t (test-times)] [-q | -c <commond>]\n");printf("-t (test-times) : run test for (test-times) times\n");printf("-q : without compile\n");printf("-c <commond> : commonds for compile\n");exit(1);}void Genarg(int argc, char const *argv[]) {if (argc < 4) PrintHelp();for (int i = 4; i < argc; ++i) {if (strcmp(argv[i], "-q") == 0) ifcpl = 0;else if (strcmp(argv[i], "-t") == 0) {++i;if (i >= argc) PrintHelp();test_times = atoi(argv[i]);} else if (strcmp(argv[i], "-c") == 0) {++i;if (i >= argc) PrintHelp();comd = argv[i];} else PrintHelp();}}int main(int argc, char const *argv[]) {Genarg(argc, argv);printf("total: %d test\n", test_times);if (ifcpl) {int fg = 0;printf("building...\n");tmp = "g++ " + string(argv[1]) + " -o .std " + comd; fg |= system(tmp.c_str());tmp = "g++ " + string(argv[2]) + " -o .tst " + comd; fg |= system(tmp.c_str());tmp = "g++ " + string(argv[3]) + " -o .mk " + comd; fg |= system(tmp.c_str());if (fg) {printf("complie error!\n");return 2;} elseprintf("completed!\n");}for (int t = 1; t <= test_times; ++t) {printf("test #%d\n", t);system(".mk > .in.txt");int Tstd, Ttst;setclock(); system(".std < .in.txt > .ans.txt"); Tstd = getclock(); printf("std: %dms ", Tstd);setclock(); system(".tst < .in.txt > .out.txt"); Ttst = getclock(); printf("tst: %dms\n", Ttst);if (system("fc .ans.txt .out.txt")) {printf("Wrong Answer !\n");getchar();}}return 0;}
#include <bits/stdc++.h>#ifndef DEBUGER#define DEBUGER#ifdef DEBUG#define see(a) cerr<<#a<<" = "<<a<<" "#define seeln(a) cerr<<#a<<" = "<<a<<endl#define put(a) cerr<<a#define outarr(_a,_l,_r) for(int _i=(_l);_i<=(_r);_i++) cerr<<#_a"["<<_i<<"]="<<_a[_i]<<" ";cerr<<endl;#define Outarr(_a,_l,_r) cerr<<#_a<<" ["<<_l<<", "<<_r<<"] : "; for(int i=(_l);i<=(_r);++i) cerr<<_a[i]<<" ";cerr<<endl;#define out(a) cerr<<a<<" "#define outln(a) cerr<<a<<endl#else#define see(a) ;#define seeln(a) ;#define put(a);#define outarr(_a,_l,_r) ;#define Outarr(_a,_l,_r) ;#define out(a) ;#define outln(a) ;#endifusing namespace std;template<typename Tp>ostream &operator<<(ostream &out, vector<Tp> vt) {out << "vector of size = " << vt.size() << " : { " ;for (size_t i = 0; i < vt.size(); ++i) out << vt[i] << ", ";return out << "} ";}template<typename Tp>istream &operator>>(istream &in, vector<Tp> &vt) {for (size_t i = 0; i < vt.size(); ++i) in >> vt[i];return in;}template<typename Tp>ostream &operator<<(ostream &out, set<Tp> st) {out << "set of size = " << st.size() << " : { " ;for (auto it = st.begin(); it != st.end(); ++it) out << *it << ", ";return out << "} ";}template<typename Tp>ostream &operator<<(ostream &out, multiset<Tp> st) {out << "multiset of size = " << st.size() << " : { " ;for (auto it = st.begin(); it != st.end(); ++it) out << *it << ", ";return out << "} ";}template<typename Tp1, typename Tp2>ostream &operator<<(ostream &out, map<Tp1, Tp2> mp) {out << "map of size = " << mp.size() << " : { " ;for (auto it = mp.begin(); it != mp.end(); ++it)out << "\"" << it->first << "\": " << it->second << ", ";return out << "} ";}template<typename Tp1, typename Tp2>ostream &operator<<(ostream &out, pair<Tp1, Tp2> P) {return out << "(" << P.first << ", " << P.second << ")";}#endif
#include <iostream>#include <cstdio>#ifndef FASTIO#define FASTIOclass myin {private:static const int MAX = 1 << 20;char buf[MAX], *p1 = buf, *p2 = buf;inline char gc() {#ifdef DEBUGreturn getchar();#endifif (p1 != p2) return *p1++;p1 = buf; p2 = p1 + fread(buf, 1, MAX, stdin); return (p1 == p2) ? (EOF) : (*p1++);}public:myin &operator>>(char *s) {char ch = gc();while (ch == '\n' || ch == '\r' || ch == ' ') ch = gc();while (ch != '\n' && ch != '\r' && ch != ' ') *s++ = ch, ch = gc();*s = '\0';return *this;}template <typename Tp>myin &operator>>(Tp &x) {x = 0; char ch = gc(); bool f = 0;while (ch < '0' || ch > '9') {(ch == '-') &&(f ^= 1); ch = gc();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (Tp)(ch ^ 48), ch = gc();if (f)(x = -x);return *this;}myin &operator>>(double &x) {x = 0; bool f = 0; char ch = gc();while (ch < '0' || ch > '9') {(ch == '-') &&(f ^= 1); ch = gc();}while (ch >= '0' && ch <= '9') x = x * 10 + (double)(ch ^ 48), ch = gc();if (ch == '.') {ch = gc(); double e = 0.1;while (ch >= '0' && ch <= '9') x = x + e * (double)(ch ^ 48), e *= 0.1, ch = gc();}if (f) x = -x;return *this;}} fin;class myout {private:static const int MAX = 1 << 20;char buf[MAX], *p1 = buf, *p2 = buf + MAX;char dbform[10] = "%.6lf";inline void pc(const char c) {#ifdef DEBUGputchar(c); return ;#endifif (p1 != p2) *p1++ = c;else {fwrite(buf, p1 - buf, 1, stdout); p1 = buf; *p1++ = c;}}template <typename _Tp> void write(_Tp x) {if (x < 0) x = -x, pc('-');if (x >= (_Tp)10) write(x / 10);pc(x % 10 + '0');}public:void flush() {fwrite(buf, p1 - buf, 1, stdout); p1 = buf;}myout &operator<<(const char *s) { for (const char *p = s; *p; ++p) pc(*p); return *this;}myout &operator<<(char *s) { for (char *p = s; *p; ++p) pc(*p); return *this;}myout &operator<<(const char s) {pc(s); return *this;}template <typename Tp> myout &operator<<(Tp x) {write(x); return *this;}myout &operator<<(myout & (*__pf)(myout &)) {return __pf(*this);}void setpoint(int n) {sprintf(dbform + 1, ".%dlf", n);}myout &operator<<(double x) {static char num[100];sprintf(num, dbform, x);return *this << num;}} fout;inline myout &edl(myout &out) {out << "\n"; out.flush(); return out;}#endif
#include <cstdio>namespace IO {const int MAX = 1 << 20;char buf[MAX], Buf[MAX], * p1 = buf, * p2 = buf, * P1 = Buf, * P2 = Buf + MAX;inline char gc() {#ifdef DEBUGreturn getchar();#endifif (p1 != p2) return *p1++;p1 = buf; p2 = p1 + fread(buf, 1, MAX, stdin); return (p1 == p2) ? (EOF) : (*p1++);}inline void pc(const char c) {#ifdef DEBUGreturn putchar(c), void();#endifif (P1 != P2) *P1++ = c;else { fwrite(Buf, P1 - Buf, 1, stdout); P1 = Buf; *P1++ = c; }}void readstr(char *s, bool fg = 0) { // fg=1 for getlinechar ch = gc();while (ch == '\n' || ch == '\r' || (!fg && ch == ' ')) ch = gc();while (ch != '\n' && ch != '\r' && (fg || ch != ' ')) *s++ = ch, ch = gc();*s = '\0';}void writestr(const char *s, char ch = '\0') { for (const char *p = s; *p; ++p) pc(*p); (ch != '\0') &&(pc(ch), 1); }template <typename _Tp> void read(_Tp &x) {x = 0; char ch = gc(); int f = 0;while (ch < '0' || ch > '9') { (ch == '-') &&(f ^= 1); ch = gc(); }while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = gc();f &&(x = -x);}template<typename Tp, typename... Args>void read(Tp &t, Args &... args) { read(t); read(args...); }template<typename Tp> void write(Tp x, char ch = '\n') {static int buf[100], d;if (x == 0) pc('0');else {if (x < 0) pc('-'), x = -x;for (d = 0; x; x /= 10) buf[++d] = x % 10 + 48;while (d) pc((char)buf[d--]);}if (ch != '\0') pc(ch);}template <typename Tp, typename... Args> void write(Tp x, Args ...args) { write(x, ' '); write(args...); }void flush() { fwrite(Buf, P1 - Buf, 1, stdout); P1 = Buf; }struct _flusher {~_flusher() { flush(); }} flusher;}using IO::read; using IO::write; using IO::readstr; using IO::writestr;int main() {return 0;}
// 莫队二次离线#include <bits/stdc++.h>template <typename Tp>inline void read(Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1;ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}using namespace std;typedef long long ll;const int N = 100010;struct mds {int l, r, id, fg;};vector<mds> mdl[N], mdr[N];vector<mds>::iterator mt;vector<int>::iterator it;int a[N], n, m, K;int L[N], R[N], t[N], bl[N], B;ll Fl[N], Fr[N], ans[N];bool cmp(int x, int y) {if (bl[L[x]] == bl[L[y]]) return R[x] < R[y];return L[x] < L[y];}void init() {// init Fr,Flfor (int i = 1; i < n; ++i) {// Fr(i) = f([1,i],i+1)}for (int i = n - 1; i >= 1; --i) {// Fl(i) = f([i+1,n],i)}for (int i = 2; i <= n; ++i) Fl[i] += Fl[i - 1], Fr[i] += Fr[i - 1];}void solve() {for (int x = 1; x <= n; ++x) {// updata(a[x])for (mt = mdr[x].begin(); mt != mdr[x].end(); ++mt)for (int i = mt->l; i <= mt->r; ++i) ans[mt->id] += mt->fg * (1/*query(a[i])*/);}for (int x = n; x >= 1; --x) {// updata(a[x])for (mt = mdl[x].begin(); mt != mdl[x].end(); ++mt)for (int i = mt->l; i <= mt->r; ++i) ans[mt->id] += mt->fg * (1/*query(a[i])*/);}}int main() {read(n); read(m); read(K);for (int i = 1; i <= n; ++i) read(a[i]);B = sqrt(n);for (int i = 1; i <= n; ++i) bl[i] = (i - 1) / B + 1;for (int i = 1; i <= m; ++i) read(L[i]), read(R[i]), t[i] = i;sort(t + 1, t + m + 1, cmp);init();int l = 1, r = 1;for (int i = 1; i <= m; ++i) {int id = t[i];if (r < R[id]) {ans[id] += Fr[R[id] - 1] - Fr[r - 1];mdr[l - 1].push_back(mds{ r + 1, R[id], id, -1 }); r = R[id];}if (l > L[id]) {ans[id] += Fl[l - 1] - Fl[L[id] - 1];mdl[r + 1].push_back(mds{ L[id], l - 1, id, -1 }); l = L[id];}if (r > R[id]) {ans[id] -= Fr[r - 1] - Fr[R[id] - 1];mdr[l - 1].push_back(mds{ R[id] + 1, r, id, 1 }); r = R[id];}if (l < L[id]) {ans[id] -= Fl[L[id] - 1] - Fl[l - 1];mdl[r + 1].push_back(mds{ l, L[id] - 1, id, 1 }); l = L[id];}}solve();for (int i = 1; i <= m; ++i) ans[t[i]] += ans[t[i - 1]];for (int i = 1; i <= m; ++i)printf("%lld\n", ans[i]);return 0;}
/*FFT 快速傅立叶变换加法卷积*/#include <bits/stdc++.h>#define _max(x,y) ((x>y)?x:y)#define _min(x,y) ((x<y)?x:y)using namespace std;typedef long long ll;template<typename _Tp>inline void red(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}template<typename _Tp> bool umax(_Tp &x, _Tp y) {return (x < y) ? (x = y, true) : (false);}template<typename _Tp> bool umin(_Tp &x, _Tp y) {return (x > y) ? (x = y, true) : (false);}typedef double db;const int N = 2097152;const db Pi = acos(-1);struct com {db r, i;com(): r(0), i(0) {}com(db _r, db _i): r(_r), i(_i) {}com(int n): r(cos(Pi * 2 / n)), i(sin(Pi * 2 / n)) {} // w_n^1com operator+(const com &b)const {return com(r + b.r, i + b.i);}com operator-(const com &b)const {return com(r - b.r, i - b.i);}com operator*(const com &b)const {return com(r * b.r - i * b.i, i * b.r + r * b.i);}} A[N], B[N];int n, m, tot;namespace sol1 { // 分治版FFTcom sav[N];// flag = 1 DFT flag = -1 IDFTvoid FFT(com *f, int n, int flag) {if (n == 1) return ;com *fl = f, *fr = f + n / 2, Dt(n), w(1, 0);Dt.i *= flag;for (int i = 0; i < n; ++i) sav[i] = f[i];for (int i = 0; i < n / 2; ++i) fl[i] = sav[i << 1], fr[i] = sav[i << 1 | 1];FFT(fl, n / 2, flag); FFT(fr, n / 2, flag);for (int i = 0; i < n / 2; ++i) {com tmp = w * fr[i];sav[i] = fl[i] + tmp;sav[i + n / 2] = fl[i] - tmp;w = w * Dt;}for (int i = 0; i < n; ++i) f[i] = sav[i];}}namespace sol2 { // 迭代版FFT (小常数)int rev[N];void FFT(com f[], int n, int fg) {for (int i = 0; i < n; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (n >> 1) : 0);for (int i = 0; i < n; ++i)(i < rev[i]) && (swap(f[i], f[rev[i]]), 1);for (int h = 2; h <= n; h <<= 1) {com Dt(h), w, tt; Dt.i *= fg;int len = (h >> 1);for (int j = 0; j < n; j += h) {w = com(1, 0);for (int k = j; k < j + len; ++k) {tt = f[k + len] * w;f[k + len] = f[k] - tt;f[k] = f[k] + tt;w = w * Dt;}}}}}int main() {red(n); red(m);for (int i = 0; i <= n; ++i) scanf("%lf", &A[i].r);for (int i = 0; i <= m; ++i) scanf("%lf", &B[i].r);tot = n + m; n = ceil(log2(n + m + 2)); n = 1 << n;using namespace sol2;FFT(A, n, 1); FFT(B, n, 1);for (int i = 0; i < n; ++i) A[i] = A[i] * B[i];FFT(A, n, -1);for (int i = 0; i <= tot; ++i) printf("%d ", (int)(A[i].r / n + 0.49));puts("");return 0;}
/*FMT/FWT 快速莫比乌斯/沃尔什变换位运算卷积*/#include <bits/stdc++.h>#define re register#define cpy(f,g,n) memcpy(f,g,sizeof(long long)*(n))#define clr(f,n) memset(f,0,sizeof(long long)*(n))#define out(f,n) for(int i=0;i<(n);++i) printf("%lld ",f[i]);puts("")#define MOD(x) ((x<mod)?(x):((x)%mod))template <typename T>inline void red(T &x) {x = 0; bool f = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') f ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (T)(ch ^ 48), ch = getchar();if (f) x = -x;}using namespace std;typedef long long ll;const int N = 1 << 18;const int mod = 998244353;const int inv2 = 499122177;ll A[N], B[N], C[N], ta[N], tb[N]; int n;inline void FMT_OR(ll f[], int n, int fg) { // fg=1 for FMT ; fg=0 for IFMTfor (re int h = 2, k = 1; h <= n; h <<= 1, k <<= 1)for (re int i = 0; i < n; i += h)for (re int j = 0; j < k; ++j)f[i + j + k] = MOD(f[i + j + k] + f[i + j] * fg + mod);}inline void FMT_AND(ll f[], int n, int fg) { // fg=1 for FMT ; fg=0 for IFMTfor (re int h = 2, k = 1; h <= n; h <<= 1, k <<= 1)for (re int i = 0; i < n; i += h)for (re int j = 0; j < k; ++j)f[i + j] = MOD(f[i + j] + f[i + j + k] * fg + mod);}inline void FWT_XOR(ll f[], int n, int fg) { // fg=1 for FWT; fg=1/2(inv 2) for IFWTll t;for (re int h = 2, k = 1; h <= n; h <<= 1, k <<= 1)for (re int i = 0; i < n; i += h)for (re int j = 0; j < k; ++j)t = f[i + j + k], f[i + j + k] = MOD(f[i + j] - t + mod), f[i + j] = MOD(f[i + j] + t),f[i + j] = MOD(f[i + j] * fg), f[i + j + k] = MOD(f[i + j + k] * fg);}void times(ll f[], ll g[], int n) {for (int i = 0; i < n; ++i) f[i] = MOD(f[i] * g[i]);}int main() {red(n); n = 1 << n;for (re int i = 0; i < n; ++i) red(A[i]);for (re int i = 0; i < n; ++i) red(B[i]);cpy(ta, A, n); cpy(tb, B, n); FMT_OR(ta, n, 1); FMT_OR(tb, n, 1); times(ta, tb, n); FMT_OR(ta, n, -1);out(ta, n);cpy(ta, A, n); cpy(tb, B, n); FMT_AND(ta, n, 1); FMT_AND(tb, n, 1); times(ta, tb, n); FMT_AND(ta, n, -1);out(ta, n);cpy(ta, A, n); cpy(tb, B, n); FWT_XOR(ta, n, 1); FWT_XOR(tb, n, 1); times(ta, tb, n); FWT_XOR(ta, n, inv2);out(ta, n);}
// 拉格朗日插值法// L(x)=\sum_{j=0}^n y_j\prod_{i\ne j}\frac{x-x_i}{x_j-x_i}#include <bits/stdc++.h>using namespace std;typedef long long ll;const int N = 1000010;const int mod = 1e9 + 7;int n, k;ll fpow(ll a, ll b, ll p = mod) {ll r = 1;for (; b; b >>= 1, a = (a * a) % p) if (b & 1) r = (r * a) % p;return r;}ll s[N], p[N], fac[N], inv[N], ifac[N];void init(int n) {fac[0] = fac[1] = inv[0] = inv[1] = ifac[0] = ifac[1] = 1;for (int i = 2; i <= n; ++i) fac[i] = fac[i - 1] * i % mod;for (int i = 2; i <= n; ++i) inv[i] = (mod - mod / i) * inv[mod % i] % mod;for (int i = 2; i <= n; ++i) ifac[i] = ifac[i - 1] * inv[i] % mod;}ll lagrange(int n, ll k, ll x[], ll y[]) { // O(n^2)ll r = 0;for (int j = 0; j < n; ++j) {ll P1 = 1, P2 = 1;for (int i = 0; i < n; ++i) if (i != j) {P1 = (P1 * (k - x[i] + mod)) % mod;P2 = (P2 * (x[j] - x[i] + mod)) % mod;}r = (r + y[j] * P1 % mod * fpow(P2, mod - 2, mod) % mod) % mod;}return r;}ll lagrange_y(int n, ll k, ll y[]) { // 当 x_i = i (i in [0, n]) O(n)init(n);p[0] = 1;for (int i = 0; i < n; ++i) p[i + 1] = p[i] * (k - i + mod) % mod;s[n] = 1;for (int i = n; i >= 1; --i) s[i - 1] = s[i] * (k - i + mod) % mod;ll r = 0;for (int j = 0; j <= n; ++j) {ll tmp = p[j] * s[j] % mod * ifac[j] % mod * ifac[n - j] % mod;r = (r + (ll)(((n - j) & 1) ? (mod - 1) : 1) * y[j] % mod * tmp % mod) % mod;}return r;}
/*NTT 快速数论变换FFT的取模形式*/#include <bits/stdc++.h>#define MOD(x) ((x<p)?(x):((x)%p))template <typename T>inline void red(T &x) {x = 0; bool f = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') f ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (T)(ch ^ 48), ch = getchar();if (f) x = -x;}using namespace std;typedef long long ll;const int p = 998244353; // = 119*2^23+1 g=3 是其原根const int G = 3;const int invG = 332748118;const int N = 2097152;int n, m, rev[N], tot;ll A[N], B[N];// NTT 对模数有要求,如果 p = r*2^k+1 是素数,在 mod p 意义下可处理 2^k 以内数据// 与 FFT 的区别,单位根 w1 = g^((p-1)/n)ll fpow(ll a, ll b, ll p =::p) {ll r = 1; for (; b; b >>= 1, a = MOD(a * a)) if (b & 1) r = MOD(r * a); return r;}// fg=1 DFT fg=0 IDFTvoid NTT(ll f[], int n, bool fg) {for (int i = 0; i < n;++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (n >> 1) : 0); // 可以放到外面预处理for (int i = 0; i < n; ++i)(rev[i] < i) && (swap(f[i], f[rev[i]]), 1);for (int h = 2; h <= n; h <<= 1) {int len = h >> 1;ll Dt = fpow(fg ? G : invG, (p - 1) / h), w;for (int j = 0; j < n; j += h) {w = 1;for (int k = j; k < j + len; ++k) {ll tt = MOD(w * f[k + len]);f[k + len] = f[k] - tt; (f[k + len] < 0) &&(f[k + len] += p);f[k] = f[k] + tt; (f[k] > p) &&(f[k] -= p);w = MOD(w * Dt);}}}if (fg == 0) {ll invn = fpow(n, p - 2);for (int i = 0; i < n; ++i) f[i] = MOD(f[i] * invn);}}int main() {red(n); red(m);for (int i = 0; i <= n; ++i) red(A[i]);for (int i = 0; i <= m; ++i) red(B[i]);tot = n + m + 1;n = ceil(log2(n + m + 2)); n = 1 << n;NTT(A, n, 1); NTT(B, n, 1);for (int i = 0; i < n; ++i) A[i] = MOD(A[i] * B[i]);NTT(A, n, 0);for (int i = 0; i < tot; ++i) printf("%lld ", A[i]);printf("\n");}
/*NTT 多项式全家桶p_mul 乘法; p_inv 求逆; p_div 带余数除法; p_sqrt 开方;p_ln Ln; p_exp EXP; p_int 积分; p_der 求导; p_pow 快速幂;DCFFT 分治 FFT 板子;to be continue ...多项式三角函数,多项式反三角函数,多项式多点求值,多项式快速差值.....*/#include <algorithm>#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#define clr(f,n) memset(f,0,sizeof(long long)*(n))#define cpy(f,g,n) memcpy(f,g,sizeof(long long)*(n))#define Outarr(x,n) cerr<<#x<<" : "; for(int i=0;i<n;++i) cerr<<x[i]<<" ";cout<<endl;#define outarr(x,n) for(int i=0;i<n;++i) printf("%lld%c",x[i],(i==n-1)?'\n':' ');#define MOD(x) ((x)<mod?(x):((x)%mod))using namespace std;template<typename _Tp>inline void red(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}typedef long long ll;namespace poly {const int mod = 998244353;const int N = (1 << 19);const int _G = 3;const int _iG = 332748118;const int inv2 = 499122177;ll fpow(ll a, ll b, ll p) {ll r = 1;for (; b; a = a * a % p, b >>= 1) if (b & 1) r = r * a % p;return r;}int rev[N], rev_n;void prerev(int n) {if (n == rev_n) return;rev_n = n;for (int i = 0; i < n; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (n >> 1) : 0);}// NTT : fg=1 DFT fg=-1 IDFTvoid NTT(ll f[], int n, int fg) {prerev(n);for (int i = 0; i < n; ++i) if (i < rev[i]) swap(f[i], f[rev[i]]);for (int h = 2; h <= n; h <<= 1) {ll Dt = fpow((fg == 1) ? _G : _iG, (mod - 1) / h, mod), w;int len = h >> 1;for (int j = 0; j < n; j += h) {w = 1;for (int k = j; k < j + len; ++k) {ll tmp = MOD(f[k + len] * w);f[k + len] = f[k] - tmp; (f[k + len] < 0) &&(f[k + len] += mod);f[k] = f[k] + tmp; (f[k] >= mod) &&(f[k] -= mod);w = MOD(w * Dt);}}}if (fg == -1) {ll invn = fpow(n, mod - 2, mod);for (int i = 0; i < n; ++i) f[i] = MOD(f[i] * invn);}}// f(x) = f*g(x) n = def f ; m = def g ; len = 最终长度(保留几位)void p_mul(ll f[], ll g[], int n, int m, int len) {static ll a[N], b[N];int nn = 1 << (int)ceil(log2(n + m - 1));clr(a, nn); clr(b, nn); cpy(a, f, n); cpy(b, g, m);NTT(a, nn, 1); NTT(b, nn, 1);for (int i = 0; i < nn; ++i) a[i] = MOD(a[i] * b[i]);NTT(a, nn, -1);for (int i = 0; i < len; ++i) f[i] = a[i];}// f(x) = g^-1(x) f(x) 为 g(x) 模 x^n 意义下的逆void p_inv(ll g[], int n, ll f[]) {static ll sav[N];int nn = 1 << (int)ceil(log2(n));clr(f, n * 2);f[0] = fpow(g[0], mod - 2, mod);for (int h = 2; h <= nn; h <<= 1) {cpy(sav, g, h); clr(sav + h, h);NTT(sav, h << 1, 1); NTT(f, h << 1, 1);for (int i = 0; i < (h << 1); ++i)f[i] = f[i] * (2ll - f[i] * sav[i] % mod + mod) % mod;NTT(f, h << 1, -1); clr(f + h, h);}clr(f + n, nn * 2 - n);}// f^2(x) = g(x) f(x) 为 g(x) 模 x^n 意义下的开方void p_sqrt(ll g[], int n, ll f[]) {static ll sav[N], r[N];int nn = 1 << (int)ceil(log2(n));clr(f, n * 2); f[0] = 1; // g[0] should be 1 otherwisefor (int h = 2; h <= nn; h <<= 1) {cpy(sav, g, h); clr(sav + h, h); p_inv(f, h, r);NTT(sav, h << 1, 1); NTT(r, h << 1, 1);for (int i = 0; i < (h << 1); ++i) sav[i] = MOD(sav[i] * r[i]);NTT(sav, h << 1, -1);for (int i = 0; i < h; ++i) f[i] = MOD((f[i] + sav[i]) * inv2);clr(f + h, h);}clr(f + n, nn * 2 - n);}// f(x) = g(x) * q(x) + r(x) : q(x) 为商 r(x) 为余数void p_div(ll f[], ll g[], int n, int m, ll q[], ll r[]) {static ll sav1[N], sav2[N];int nn;for (nn = 1; nn < n - m + 1; nn <<= 1);clr(sav1, nn); clr(sav2, nn); cpy(sav1, f, n); cpy(sav2, g, m);reverse(sav1, sav1 + n); reverse(sav2, sav2 + m);p_inv(sav2, n - m + 1, q); p_mul(q, sav1, n - m + 1, n, n - m + 1);reverse(q, q + n - m + 1); cpy(r, g, m);p_mul(r, q, m, n - m + 1, m - 1);for (int i = 0; i < m - 1; ++i) r[i] = MOD(f[i] - r[i] + mod);}// 预处理乘法逆元ll inv[N];void Initinv(int n) {inv[0] = inv[1] = 1;for (int i = 2; i <= n; ++i) inv[i] = (mod - mod / i) * inv[mod % i] % mod;}// 对 f(x) 进行积分 Initinv() firstvoid p_int(ll f[], int n) {for (int i = n - 1; i; --i) f[i] = MOD(f[i - 1] * inv[i]);f[0] = 0;}// 对 f(x) 进行求导void p_der(ll f[], int n) {for (int i = 1; i < n; ++i) f[i - 1] = MOD(f[i] * i);f[n - 1] = 0;}// f(x) <- ln f(x) f[0] should be 1void p_ln(ll f[], int n) {static ll g[N];p_inv(f, n, g); p_der(f, n);p_mul(f, g, n, n, n + n);p_int(f, n);}// f(x) <- exp f(x) (倍增版) f[0] should be 0void p_exp(ll f[], int n) {static ll g[N], sav[N];clr(g, n * 2); clr(sav, n * 2); g[0] = 1;for (int h = 2; h <= n; h <<= 1) {cpy(sav, g, h); p_ln(sav, h);for (int i = 0; i < h; ++i) sav[i] = MOD(f[i] - sav[i] + mod);sav[0] = MOD(sav[0] + 1);p_mul(g, sav, h, h, h);}cpy(f, g, n);}/*void _p_exp(ll f[],ll g[],int l,int r) {static ll A[N],B[N];if(r-l==1) {if(l>0) f[l]=MOD(f[l]*fpow(l,mod-2,mod));return ;}int mid=(l+r)>>1,len=mid-l;_p_exp(f,g,l,mid);cpy(A,f+l,len); clr(A+len,len); cpy(B,g,len<<1);p_mul(A,B,len<<1,len<<1,len<<1);for(int i=mid;i<r;++i) f[i]=MOD(f[i]+A[i-l]);_p_exp(f,g,mid,r);}// f(x) <- exp f(x) (分治 FFT 版) f[0] should be 0void p_exp(ll f[],int n) {static ll g[N];cpy(g,f,n); clr(f,n); f[0]=1;for(int i=0;i<n;++i) g[i]=MOD(g[i]*i);_p_exp(f,g,0,n);}*/// f(x) <- f^k(x) f(x) 模 x^n 意义下的 k 次void p_pow(ll f[], int n, ll k) {p_ln(f, n);for (int i = 0; i < n; ++i) f[i] = MOD(f[i] * k);p_exp(f, n);}// 分治FFT [l,r) F[n] = sum(0<i<=n) F[n-i]G[i]void DCFFT(ll f[], ll g[], int l, int r) {static ll A[N], B[N];if (r - l == 1) return ;int mid = (l + r) >> 1, len = mid - l;DCFFT(f, g, l, mid);cpy(A, f + l, len); clr(A + len, len); cpy(B, g, len << 1);p_mul(A, B, len << 1, len << 1, len << 1);for (int i = mid; i < r; ++i) f[i] = MOD(f[i] + A[i - l]);DCFFT(f, g, mid, r);}}using namespace poly;int main() {return 0;}
// AC 自动机,字符串多模式串匹配#include <bits/stdc++.h>using namespace std;namespace ACAM {const int MAX = 200010;int tr[MAX][26], fail[MAX], sz;int tag[MAX];void init() {memset(tr[0], 0, sizeof(tr[0]));fail[0] = 0; sz = 0;}int newnode() {++sz; fail[sz] = 0; memset(tr[sz], 0, sizeof(tr[sz]));return sz;}int insert(string &s) {int p = 0, c;for (int i = 0; i < s.size(); ++i) {c = s[i] - 'a';if (tr[p][c] == 0) tr[p][c] = newnode();p = tr[p][c];}return p;}void build() {queue<int> q;for (int i = 0; i < 26; ++i) {if (tr[0][i]) q.push(tr[0][i]);}while (!q.empty()) {int u = q.front(); q.pop();for (int i = 0; i < 26; ++i) {if (tr[u][i]) fail[tr[u][i]] = tr[fail[u]][i], q.push(tr[u][i]);else tr[u][i] = tr[fail[u]][i];}}}void query(string &s) {int cur = 0, c;for (int i = 0; i <= sz; ++i) tag[i] = 0;for (int i = 0; i < s.size(); ++i) {c = s[i] - 'a';cur = tr[cur][c];tag[cur]++;}}void work() {static int idg[MAX];for (int i = 0; i <= sz; ++i) idg[i] = 0;for (int i = 1; i <= sz; ++i) ++idg[fail[i]];queue<int> q;for (int i = 1; i <= sz; ++i) if (idg[i] == 0) q.push(i);while (!q.empty()) {int u = q.front(); q.pop();if (!u) break;tag[fail[u]] += tag[u];if (--idg[fail[u]] == 0) q.push(fail[u]);}}}int n, ed[200005];string P[200005], T;int main() {cin >> n;ACAM::init();for (int i = 0; i < n; ++i)cin >> P[i], ed[i] = ACAM::insert(P[i]);ACAM::build();cin >> T;ACAM::query(T);ACAM::work();for (int i = 0; i < n; ++i)cout << ACAM::tag[ed[i]] << "\n";return 0;}
// EXSAM 广义后缀自动机#include <bits/stdc++.h>template<typename _Tp>inline void read(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}template<typename _Tp, typename... Args>void read(_Tp &t, Args &... args) {read(t); read(args...);}using namespace std;typedef long long ll;typedef pair<int, int> P;const int N = 1000010;namespace EXSAM {const int MAX = 2000010;struct sta {int len, link;int nxt[26];int &operator[](const int k) {return nxt[k];}} st[MAX];int sz;void init() {sz = 1; st[0].link = -1;}void _extend(int last, int c) {int cur = st[last][c], p = st[last].link; st[cur].len = st[last].len + 1;while (p != -1 && st[p][c] == 0) {st[p][c] = cur; p = st[p].link;}if (p == -1) st[cur].link = 0;else {int q = st[p][c];if (st[q].len == st[p].len + 1) st[cur].link = q;else {int cp = sz++; st[cp].len = st[p].len + 1; st[cp].link = st[q].link;for (int i = 0; i < 26; ++i) st[cp][i] = (st[st[q][i]].len == 0) ? 0 : st[q][i];st[cur].link = st[q].link = cp;while (p != -1 && st[p][c] == q) {st[p][c] = cp;p = st[p].link;}}}}void build() {queue<P> q;for (int i = 0; i < 26; ++i) if (st[0][i] != 0) q.push(P(0, i));while (!q.empty()) {P u = q.front(); q.pop();_extend(u.first, u.second);int o = st[u.first][u.second];for (int i = 0; i < 26; ++i) if (st[o][i] != 0) q.push(P(o, i));}}void insert(char *s, int len) {int cur = 0;for (int i = 0; i < len; ++i) {if (st[cur][s[i] - 'a'] == 0) st[cur][s[i] - 'a'] = sz++;cur = st[cur][s[i] - 'a'];}}ll solve() {ll r = 0;for (int i = 1; i < sz; ++i) r += st[i].len - st[st[i].link].len;return r;}}int n; char s[N];int main() {read(n);EXSAM::init();for (int i = 1; i <= n; ++i) {scanf("%s", s);EXSAM::insert(s, strlen(s));}EXSAM::build();printf("%lld\n", EXSAM::solve());return 0;}
// KMP#include <bits/stdc++.h>using namespace std;const int N = 1000010;char P[N], T[N];int nxt[N], f[N], n, m;void getnxt() {nxt[1] = 0;for (int i = 2, j = 0; i <= m; ++i) {while (j > 0 && P[i] != P[j + 1]) j = nxt[j];if (P[i] == P[j + 1]) ++j;nxt[i] = j;}}void KMP() {for (int i = 1, j = 0; i <= n; ++i) {while (j > 0 && (j == m || T[i] != P[j + 1])) j = nxt[j];if (T[i] == P[j + 1]) ++j;f[i] = j;}}int main() {scanf("%s%s", T + 1, P + 1);n = strlen(T + 1), m = strlen(P + 1);getnxt();KMP();for (int i = 1; i <= n; ++i) if (f[i] == m) printf("%d\n", i - m + 1);for (int i = 1; i <= m; ++i) printf("%d%c", nxt[i], " \n"[i == m]);return 0;}
/*manachar 马拉车算法--> 线性求最长回文串Oi-wiki(Manacher) --> https://oi-wiki.org/string/manacher/*/#include <bits/stdc++.h>using namespace std;const int N = 1.2e7;char s[N], str[N << 1];int p[N << 1];int manacher() {int len = strlen(s), n = 0;str[n++] = '$'; str[n++] = '#';for (int i = 0; i < len; i++) str[n++] = s[i], str[n++] = '#'; str[n] = '\0';int mr = 0, ans = 0, mid = 0;for (int i = 1; i < n; i++) {p[i] = i < mr ? min(p[2 * mid - i], mr - i) : 1;while (str[i - p[i]] == str[i + p[i]]) p[i]++;if (p[i] + i > mr) mr = p[i] + i, mid = i;ans = max(ans, p[i]);}return ans - 1;}int main() {scanf("%s", s);printf("%d\n", manacher());}
// 最小表示法#include <bits/stdc++.h>template<typename _Tp>inline void read(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}template<typename _Tp, typename... Args>void read(_Tp &t, Args &... args) {read(t); read(args...);}using namespace std;typedef long long ll;const int N = 300010;int a[N], n;int minstr(int s[], int n) {int i = 0, j = 1, k = 0; // i,j 比较的两个循环串开头,k为当前相等长度while (i < n && j < n && k < n) {if (s[(i + k) % n] == s[(j + k) % n]) ++k;else {if (s[(i + k) % n] < s[(j + k) % n]) j += k + 1;else i += k + 1;// 若 s[i..k-1] == s[j..k-1] ,s[i+k]<s[j+k] 说明 j~j+k 都不可能成为最小循环串,// 因为都有对应的 i~i+k 比其更小if (i == j) ++j;k = 0;}}return min(i, j);}int main() {read(n);for (int i = 0; i < n; ++i) read(a[i]);int ps = minstr(a, n);printf("%d", a[ps]);for (int i = (ps + 1) % n; i != ps; i = (i + 1) % n) printf(" %d", a[i]);puts("");return 0;}
/*PAM 回文自动机 / 回文树luogu P5496 【模板】回文自动机(PAM)Oi-wiki --> https://oi-wiki.org/string/pam/*/#include <bits/stdc++.h>using namespace std;const int N = 500010;namespace PAM {int sz, tot, lst; // sz:状态数量 tot:字符串长度 lst:上次状态int cnt[N], sum[N], ch[N][26], len[N], fail[N]; // cnt:该状态对应原串中出现次数// fail 指针跳到该串最长后缀回文,sum 记录跳几次跳完char s[N];int newnode(int l) {++sz; memset(ch[sz], 0, sizeof(ch[sz]));len[sz] = l; fail[sz] = cnt[sz] = sum[sz] = 0;return sz;}void init() {sz = -1; lst = 0; s[tot = 0] = '$';newnode(0); newnode(-1); fail[0] = 1;}int getfail(int x) {while (s[tot - len[x] - 1] != s[tot]) x = fail[x];return x;}void insert(char c) {s[++tot] = c;int cur = getfail(lst);if (!ch[cur][c - 'a']) {int now = newnode(len[cur] + 2);fail[now] = ch[getfail(fail[cur])][c - 'a'];ch[cur][c - 'a'] = now;sum[now] = sum[fail[now]] + 1;}++cnt[lst];lst = ch[cur][c - 'a'];}void calc() {for (int i = sz; i >= 0; --i) cnt[fail[i]] += cnt[i];} // 计算每个状态出现次数}char str[N];int k;int main() {scanf("%s", str);PAM::init();for (char *ps = str; *ps; ++ps) {*ps = (*ps - 97 + k) % 26 + 97;PAM::insert(*ps);k = PAM::sum[PAM::lst]; // 以 ps 位为结尾的回文串数量printf("%d ", k);}printf("\n");return 0;}
/*后缀数组 (SA)O(nlogn) 倍增做法,外加求 height 数组Oi-wiki(后缀数组 ) --> https://oi-wiki.org/string/sa/*/#include <bits/stdc++.h>using namespace std;const int N = 1000010;typedef long long ll;int x[N], y[N], sa[N], c[N], rk[N], height[N];char s[N];int n, m;void getSA() {for (int i = 1; i <= n; ++i) ++c[x[i] = s[i]];for (int i = 2; i <= m; ++i) c[i] += c[i - 1];for (int i = n; i >= 1; --i) sa[c[x[i]]--] = i;for (int k = 1; k <= n; k <<= 1) {int num = 0;for (int i = n - k + 1; i <= n; ++i) y[++num] = i;for (int i = 1; i <= n; ++i) if (sa[i] > k) y[++num] = sa[i] - k;for (int i = 1; i <= m; ++i) c[i] = 0;for (int i = 1; i <= n; ++i) ++c[x[i]];for (int i = 2; i <= m; ++i) c[i] += c[i - 1];for (int i = n; i >= 1; --i) sa[c[x[y[i]]]--] = y[i], y[i] = 0;swap(x, y);x[sa[1]] = 1; num = 1;for (int i = 2; i <= n; ++i)x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) ? num : ++num;if (num == n) break;m = num;}}void getheight() {int k = 0;for (int i = 1; i <= n; ++i) rk[sa[i]] = i;for (int i = 1; i <= n; ++i)if (rk[i] != 1) {if (k > 0) --k;int j = sa[rk[i] - 1];while (j + k <= n && i + k <= n && s[i + k] == s[j + k]) ++k;height[rk[i]] = k;}}int main() {scanf("%s", s + 1);n = strlen(s + 1); m = 'z';getSA();// getheight();for (int i = 1; i <= n; ++i)printf("%d ", sa[i]);printf("\n");}
// SAM 后缀自动机#include <bits/stdc++.h>template<typename _Tp>inline void read(_Tp &x) {x = 0; bool fg = 0; char ch = getchar();while (ch < '0' || ch > '9') {if (ch == '-') fg ^= 1; ch = getchar();}while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + (_Tp)(ch ^ 48), ch = getchar();if (fg) x = -x;}template<typename _Tp, typename... Args>void read(_Tp &t, Args &... args) {read(t); read(args...);}using namespace std;typedef long long ll;const int N = 2000010;char s[N]; int n;namespace SAM {struct sta {int len, link;int nxt[26];};const int MAX = 2000010;sta st[MAX];int ct[MAX], deg[MAX];int sz, lst;void init() {sz = 1; st[0].len = 0; st[0].link = -1; lst = 0;}void extend(char c) {int cur = sz++, p = lst; st[cur].len = st[lst].len + 1;ct[cur]++;while (p != -1 && !st[p].nxt[c - 'a']) {st[p].nxt[c - 'a'] = cur;p = st[p].link;}if (p == -1) st[cur].link = 0;else {int q = st[p].nxt[c - 'a'];if (st[q].len == st[p].len + 1)st[cur].link = q;else {int cp = sz++;st[cp] = st[q];st[cp].len = st[p].len + 1;while (p != -1 && st[p].nxt[c - 'a'] == q) {st[p].nxt[c - 'a'] = cp;p = st[p].link;}st[cur].link = st[q].link = cp;}}lst = cur;}void solve() {for (int i = 1; i < sz; ++i)deg[st[i].link]++;queue<int> q;for (int i = 1; i < sz; ++i) {if (deg[i] == 0) q.push(i);}while (!q.empty()) {int u = q.front(), f = st[u].link; q.pop();if (f != -1) {deg[f]--; ct[f] += ct[u];if (deg[f] == 0) q.push(f);}}ll ans = 0;for (int i = 1; i < sz; ++i) {if (ct[i] > 1)ans = max(ans, (ll)ct[i] * st[i].len);}printf("%lld\n", ans);}}int main() {scanf("%s", s + 1);n = strlen(s + 1);SAM::init();for (int i = 1; i <= n; ++i) SAM::extend(s[i]);SAM::solve();return 0;}
#include <iostream>using namespace std;#define fi first#define se secondtypedef long long ll;typedef pair<ll, ll> pll;const int p1 = 1019260817; // 双模 hashconst int p2 = 1019260819;const int bs = 125641; // 基数const int N = 100000;pll operator*(const pll &a, const ll &b) {return pll(a.fi * b % p1, a.se * b % p2);}pll operator*(const pll &a, const pll &b) {return pll(a.fi * b.fi % p1, a.se * b.se % p2);}pll operator+(const pll &a, const ll &b) {return pll((a.fi + b) % p1, (a.se + b) % p2);}pll operator-(const pll &a, const pll &b) {return pll((a.fi - b.fi + p1) % p1, (a.se - b.se + p2) % p2);}pll operator+(const pll &a, const pll &b) {return pll((a.fi + b.fi) % p1, (a.se + b.se) % p2);}pll pw[N], pws[N]; // pw[i] = bs ^ i, pws[i] = \sum_{j=0}^i bs^jvoid init(int n) {pw[0] = {1, 1};for (int i = 1; i <= n; ++i) pw[i] = pw[i - 1] * bs;// pws[0] = {1, 1};// for (int i = 1; i <= n; ++i) pws[i] = pws[i - 1] + pw[i];}// ---------- 用于线段树维护 Hash ----------struct dat {pll f; // 哈希值int len; // 串长dat() { f = {0, 0}; len = 0; }dat(const pll &_f, const int &_len) { f = _f; len = _len; }};dat operator*(const dat &a, const dat &b) { // hash 值拼接return dat(a.f * pw[b.len] + b.f, a.len + b.len);}// ---------- 字符串 Hash ----------void initstr(char *S, int n, pll *f) {f[0] = pll(0, 0); init(n);for (int i = 1; i <= n; ++i)f[i] = f[i - 1] * bs + (S[i] - 'a');}pll gethash(pll *f, int l, int r) {return f[r] - f[l - 1] * pw[r - l + 1];}
// Z 函数 (EXKMP)#include <bits/stdc++.h>using namespace std;const int N = 40000010;char s[N], t[N]; int z[N], n, m;void Z_algo(char *s, int n) {for (int i = 1; i <= n; ++i) z[i] = 0;for (int i = 2, l = 0, r = 0; i <= n; ++i) {if (i <= r) z[i] = min(z[i - l + 1], r - i + 1);while (i + z[i] <= n && s[z[i] + 1] == s[i + z[i]]) ++z[i];if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;}}int main() {scanf("%s%s", s + 1, t + 1);n = strlen(s + 1), m = strlen(t + 1);t[m + 1] = '@';strcat(t + 1, s + 1);Z_algo(t, n + m + 1);return 0;}