Skip to content

Commit cc3502d

Browse files
committed
v1.0.3:增加了莫队、2-SAT和其他内容“
1 parent fe229e2 commit cc3502d

9 files changed

Lines changed: 1401 additions & 3 deletions

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
**当前最新普通版发布版本为 `v1.0.1`****最新打印版发布版本为 `v1.0.0` (总词数约7.7w(含代码))**
1+
**当前最新普通版发布版本为 `v1.0.3`****最新打印版发布版本为 `v1.0.0` (总词数约7.7w(含代码))**
22

33
成品为 `template.pdf` (移步 [releases](https://github.com/lr580/algorithm_template/releases) 查看/下载)
44

@@ -46,6 +46,13 @@
4646

4747
## 更新日志
4848

49+
- 22/05/17 - 22/05/25 (`v1.0.3`)
50+
51+
- 增加了stringstream
52+
- 增加了普通莫队、带修莫队、树上莫队和回滚莫队算法
53+
- 增加了set部分内容
54+
- 增加了2-SAT算法
55+
4956
- 22/04/19 - 22/04/22 (`v1.0.2`)
5057

5158
- 增加了KMP算法周期与border

code/at1219_mo_algo.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
#define sc(x) scanf("%lld", &x)
4+
typedef long long ll;
5+
#define mn 100010
6+
ll n, x[mn], t[mn], m, k, ans[mn], bin[mn], cnt[mn];
7+
ll sq, bn, bel[mn], lf[mn], rf[mn];
8+
struct query
9+
{
10+
ll l, r, i;
11+
bool operator<(const query &x) const
12+
{ //一定要这么排序
13+
return bel[l] == bel[x.l] ? r < x.r : bel[l] < bel[x.l];
14+
}
15+
} q[mn];
16+
void del(ll v) { --bin[v]; }
17+
void add(ll v, ll &tmp) { tmp = max(tmp, (++bin[v]) * t[v]); }
18+
signed main()
19+
{
20+
sc(n), sc(m), sq = sqrt(n), bn = n / sq;
21+
for (ll i = 1; i <= n; ++i)
22+
{
23+
sc(x[i]), t[i] = x[i];
24+
}
25+
for (ll i = 1; i <= m; ++i)
26+
{
27+
sc(q[i].l), sc(q[i].r), q[i].i = i;
28+
}
29+
for (ll i = 1; i <= bn; ++i) //一定要这么分块,不能/sq,不然会炸
30+
lf[i] = (i - 1) * sq + 1, rf[i] = i * sq;
31+
if (rf[bn] < n)
32+
++bn, lf[bn] = rf[bn - 1] + 1, rf[bn] = n;
33+
for (ll i = 1; i <= bn; ++i)
34+
for (ll j = lf[i]; j <= rf[i]; ++j)
35+
bel[j] = i;
36+
sort(q + 1, q + 1 + m);
37+
sort(t + 1, t + 1 + n);
38+
k = unique(t + 1, t + 1 + n) - (t + 1);
39+
for (ll i = 1; i <= n; ++i)
40+
{ // x[i]是输入的a[i]排在第x[i]位,离散化压[1,1e9]到[1,1e5]
41+
x[i] = lower_bound(t + 1, t + 1 + k, x[i]) - t;
42+
}
43+
ll l = 1, r = 0, la = 0, sum = 0, l2 = 0, sum2 = 0;
44+
for (ll i = 1; i <= m; ++i)
45+
{
46+
if (bel[q[i].l] == bel[q[i].r])
47+
{ // 询问的左右端点同属于一个块则暴力扫描回答
48+
for (ll j = q[i].l; j <= q[i].r; ++j)
49+
{
50+
++cnt[x[j]]; //入桶
51+
}
52+
for (ll j = q[i].l; j <= q[i].r; ++j)
53+
{ //按题意计算
54+
ans[q[i].i] = max(ans[q[i].i], t[x[j]] * cnt[x[j]]);
55+
}
56+
for (ll j = q[i].l; j <= q[i].r; ++j)
57+
{
58+
--cnt[x[j]]; //清理记忆
59+
}
60+
continue;
61+
}
62+
if (bel[q[i].l] != la) // 访问到了新的块则重新初始化莫队区间
63+
{
64+
while (r > rf[bel[q[i].l]])
65+
del(x[r--]);
66+
while (l < rf[bel[q[i].l]] + 1)
67+
del(x[l++]);
68+
sum = 0, la = bel[q[i].l];
69+
}
70+
while (r < q[i].r) // 扩展右端点
71+
add(x[++r], sum);
72+
l2 = l, sum2 = sum;
73+
while (l2 > q[i].l) // 扩展左端点
74+
add(x[--l2], sum2);
75+
ans[q[i].i] = sum2;
76+
while (l2 < l) // 回滚
77+
del(x[l2++]);
78+
}
79+
for (ll i = 1; i <= m; ++i)
80+
{
81+
printf("%lld\n", ans[i]);
82+
}
83+
return 0;
84+
}

code/p1903_mo_algo.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
#define sc(x) scanf("%lld", &x)
4+
typedef long long ll;
5+
#define mn 133340
6+
ll n, m, sq, a[mn], a0[mn], ans[mn], m1, m2, sum, bin[1000010];
7+
struct query1
8+
{
9+
ll l, r, i, c;
10+
bool operator<(const query1 &x) const
11+
{
12+
if (l / sq == x.l / sq)
13+
{
14+
return r / sq == x.r / sq ? i < x.i : r < x.r;
15+
}
16+
return l < x.l;
17+
}
18+
} q1[mn];
19+
struct query2
20+
{
21+
ll i, f, t;
22+
} q2[mn];
23+
void add(ll i)
24+
{
25+
sum += bin[i]++ == 0;
26+
}
27+
void del(ll i)
28+
{
29+
sum -= --bin[i] == 0;
30+
}
31+
ll l = 1, r;
32+
void addt(ll t)
33+
{
34+
if (l <= q2[t].i && q2[t].i <= r)
35+
del(q2[t].f), add(q2[t].t);
36+
a0[q2[t].i] = q2[t].t;
37+
}
38+
void delt(ll t)
39+
{
40+
if (l <= q2[t].i && q2[t].i <= r)
41+
del(q2[t].t), add(q2[t].f);
42+
a0[q2[t].i] = q2[t].f;
43+
}
44+
signed main()
45+
{
46+
sc(n), sc(m), sq = pow(n, 2. / 3);
47+
for (ll i = 1; i <= n; ++i)
48+
{
49+
sc(a[i]), a0[i] = a[i];
50+
}
51+
char ch[5] = {};
52+
for (ll i = 1, x, y; i <= m; ++i)
53+
{
54+
scanf("%s%lld%lld", ch, &x, &y);
55+
if (ch[0] == 'Q')
56+
{
57+
++m1, q1[m1] = {x, y, m1, m2 + 1};
58+
}
59+
else
60+
{
61+
++m2, q2[m2] = {x, a[x], y}, a[x] = y;
62+
}
63+
}
64+
sort(q1 + 1, q1 + 1 + m1);
65+
for (ll i = 1, t = 1; i <= m1; ++i)
66+
{
67+
while (t < q1[i].c)
68+
addt(t++);
69+
while (t > q1[i].c)
70+
delt(--t);
71+
while (l > q1[i].l)
72+
add(a0[--l]);
73+
while (r < q1[i].r)
74+
add(a0[++r]);
75+
while (l < q1[i].l)
76+
del(a0[l++]);
77+
while (r > q1[i].r)
78+
del(a0[r--]);
79+
ans[q1[i].i] = sum;
80+
}
81+
for (ll i = 1; i <= m1; ++i)
82+
{
83+
printf("%lld\n", ans[i]);
84+
}
85+
return 0;
86+
}

code/p3901_mo_algo.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
#define sc(x) scanf("%lld", &x)
4+
typedef long long ll;
5+
#define mn 100010
6+
ll n, m, x, bin[mn], ans[mn], sq, a[mn], sum;
7+
struct query
8+
{
9+
ll l, r, i;
10+
bool operator<(const query &x) const
11+
{
12+
if (l / sq != x.l / sq)
13+
return l < x.l;
14+
if (l / sq & 1)
15+
return r < x.r;
16+
return r > x.r;
17+
}
18+
} q[mn];
19+
void add(ll i)
20+
{
21+
sum += bin[a[i]]++ == 0;
22+
}
23+
void del(ll i)
24+
{
25+
sum -= --bin[a[i]] == 0;
26+
}
27+
signed main()
28+
{
29+
sc(n), sc(m), sq = sqrt(n);
30+
for (ll i = 1; i <= n; ++i)
31+
{
32+
sc(a[i]);
33+
}
34+
for (ll i = 1; i <= m; ++i)
35+
{
36+
sc(q[i].l), sc(q[i].r), q[i].i = i;
37+
}
38+
sort(q + 1, q + 1 + m);
39+
for (ll i = 1, l = 1, r = 0; i <= m; ++i)
40+
{
41+
while (l > q[i].l)
42+
add(--l);
43+
while (r < q[i].r)
44+
add(++r);
45+
while (l < q[i].l)
46+
del(l++);
47+
while (r > q[i].r)
48+
del(r--);
49+
ans[q[i].i] = sum == (q[i].r - q[i].l + 1);
50+
}
51+
for (ll i = 1; i <= m; ++i)
52+
{
53+
printf("%s\n", ans[i] ? "Yes" : "No");
54+
}
55+
return 0;
56+
}

code/p4782_2_sat.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
#define sc(x) scanf("%lld", &x)
4+
typedef long long ll;
5+
#define mn 2000010
6+
ll n, m, hd[mn], cnt, st, low[mn], dfn[mn], ins[mn], scc, c[mn];
7+
stack<ll> s;
8+
struct edge
9+
{
10+
ll to, nx;
11+
} e[mn * 2];
12+
void tarjan(ll u)
13+
{
14+
low[u] = dfn[u] = ++st, ins[u] = true;
15+
s.push(u);
16+
for (ll i = hd[u], v; i; i = e[i].nx)
17+
{
18+
v = e[i].to;
19+
if (!dfn[v])
20+
{
21+
tarjan(v);
22+
low[u] = min(low[u], low[v]);
23+
}
24+
else if (ins[v])
25+
{
26+
low[u] = min(low[u], dfn[v]);
27+
}
28+
}
29+
if (low[u] == dfn[u])
30+
{
31+
++scc;
32+
do
33+
{
34+
c[u] = scc;
35+
u = s.top();
36+
s.pop();
37+
ins[u] = false;
38+
} while (low[u] != dfn[u]);
39+
}
40+
}
41+
signed main()
42+
{
43+
sc(n), sc(m);
44+
auto adde = [&](ll u, ll v)
45+
{ e[++cnt] = {v, hd[u]}, hd[u] = cnt; };
46+
for (ll i = 1, a, va, b, vb; i <= m; ++i)
47+
{
48+
sc(a), sc(va), sc(b), sc(vb);
49+
if (va && vb)
50+
{
51+
adde(a + n, b), adde(b + n, a);
52+
}
53+
else if (!va && vb)
54+
{
55+
adde(a, b), adde(b + n, a + n);
56+
}
57+
else if (va && !vb)
58+
{
59+
adde(a + n, b + n), adde(b, a);
60+
}
61+
else if (!va && !vb)
62+
{
63+
adde(a, b + n), adde(b, a + n);
64+
}
65+
// i.e. adde(a+n*va,b+n*(vb^1)),adde(b+n*vb,a+n*(va^1))
66+
}
67+
for (ll i = 1; i <= 2 * n; ++i)
68+
{
69+
if (!dfn[i])
70+
{
71+
tarjan(i);
72+
}
73+
}
74+
for (ll i = 1; i <= n; ++i)
75+
{
76+
if (c[i] == c[i + n])
77+
{
78+
printf("IMPOSSIBLE");
79+
return 0;
80+
}
81+
}
82+
printf("POSSIBLE\n");
83+
for (ll i = 1; i <= n; ++i)
84+
{ // tarjan逆拓扑序
85+
printf("%d ", c[i] < c[i + n]);
86+
}
87+
return 0;
88+
}

0 commit comments

Comments
 (0)