Skip to content

Commit fe229e2

Browse files
committed
v1.0.2:增加和修改了若干内容,主要增添了部分随机化内容
1 parent 79136b9 commit fe229e2

5 files changed

Lines changed: 390 additions & 68 deletions

File tree

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,16 @@
4646

4747
## 更新日志
4848

49+
- 22/04/19 - 22/04/22 (`v1.0.2`)
50+
51+
- 增加了KMP算法周期与border
52+
- 删除了凸包一节无关多余内容
53+
- 增加了另一种写法的C语言快读
54+
- 修正了计算几何判断线段相交的错误方法
55+
- 增改了随机化的程序语法、公式和爬山算法及模拟退火例题
56+
- 重制了珂朵莉树参考模板
57+
- 微增了博弈论理论内容
58+
4959
- 22/04/06 - 22/04/07 (`v1.0.1`)
5060

5161
- 增加了位运算一节少量内容

code/hill_climbing.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include <bits/stdc++.h> //SCNUOJ1679 http://10.191.65.243:5000/p/1679
2+
using namespace std;
3+
typedef long long ll;
4+
typedef double db;
5+
ll p, a, b, q;
6+
db k, t = 0.5, d, minx = 0.5, nowx = 0.5;
7+
db f(db x) // assume k=1
8+
{
9+
return sqrt(p - a + x * x) + sqrt(p - b + (k - x) * (k - x));
10+
}
11+
signed main()
12+
{
13+
scanf("%lld%lld%lld%lld", &p, &a, &b, &q);
14+
while (q--)
15+
{
16+
scanf("%lf", &k);
17+
minx = nowx = k / 2;
18+
t = k / 2;
19+
while (t > 1e-6) // t是温度参数
20+
{
21+
db x1 = nowx + t;
22+
db x2 = nowx - t;
23+
db newx = f(x1) < f(x2) ? x1 : x2;
24+
nowx = newx;
25+
if (f(newx) < f(minx))
26+
{
27+
minx = newx;
28+
}
29+
t *= 0.9; // 降温系数
30+
}
31+
printf("%lf %lf\n", minx, (k - minx));
32+
}
33+
return 0;
34+
}

code/odt.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include <bits/stdc++.h> //SCNUOJ1731 https://oj.socoding.cn/p/1731
2+
using namespace std;
3+
#define sc(x) scanf("%lld", &x)
4+
typedef long long ll;
5+
ll n;
6+
struct node_t
7+
{
8+
ll l, r;
9+
mutable ll v; // mutable使得const可变(set元素是const)
10+
node_t(const ll &il, const ll &ir, const ll &iv) : l(il), r(ir), v(iv) {}
11+
inline bool operator<(const node_t &o) const { return l < o.l; }
12+
};
13+
set<node_t> odt; //建立一棵珂朵莉树
14+
auto split(ll x) //珂朵莉基操
15+
{
16+
if (x > n)
17+
return odt.end();
18+
auto it = --odt.upper_bound(node_t{x, 0, 0});
19+
if (it->l == x)
20+
return it;
21+
ll l = it->l, r = it->r, v = it->v;
22+
odt.erase(it);
23+
odt.insert(node_t(l, x - 1, v));
24+
return odt.insert(node_t(x, r, v)).first;
25+
}
26+
void assign(ll l, ll r, ll v) //区间赋值为v, 均摊O(loglogn)
27+
{
28+
auto itr = split(r + 1), itl = split(l);
29+
odt.erase(itl, itr);
30+
odt.insert(node_t(l, r, v));
31+
}
32+
void add(ll l, ll r, ll v) //区间增加v, 均摊O(loglogn)
33+
{
34+
auto itr = split(r + 1), itl = split(l);
35+
for (; itl != itr; ++itl) //枚举每个子区间
36+
{
37+
itl->v = itl->v + v;
38+
}
39+
}
40+
ll query(ll l, ll r) //区间查询, 均摊O(loglogn)
41+
{
42+
ll res = 0;
43+
auto itr = split(r + 1), itl = split(l);
44+
for (; itl != itr; ++itl)
45+
{ // itl->l, itl->r, itl->v 是当前子区间的左右端点和值
46+
res += (itl->r - itl->l + 1) * (itl->v);
47+
}
48+
return res;
49+
}
50+
signed main()
51+
{
52+
sc(n);
53+
odt.insert({1, n, 1236895}); //初始化区间
54+
ll m, cmd, l, r, x;
55+
for (sc(m); m--;)
56+
{
57+
sc(cmd), sc(l), sc(r);
58+
if (cmd == 1)
59+
{
60+
sc(x), assign(l, r, x);
61+
}
62+
else if (cmd == 2)
63+
{
64+
sc(x), add(l, r, x);
65+
}
66+
else
67+
{
68+
printf("%lld\n", query(l, r));
69+
}
70+
}
71+
return 0;
72+
}

code/simulated_annealing.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include <bits/stdc++.h> //SCNUOJ1730 https://oj.socoding.cn/p/1730
2+
using namespace std;
3+
#define sc(x) scanf("%lld", &x)
4+
typedef long long ll;
5+
typedef double db;
6+
ll a, b, c, d, e, l, r;
7+
db x, t, now, mx, ans = -6;
8+
db f(db x)
9+
{
10+
return sin(x / a) + sin(x / b) + sin(x / c) + sin(x / d) + sin(x / e);
11+
}
12+
void solve()
13+
{
14+
static ll rd = 1; //也可以用random_device生成种子
15+
mt19937 mt(rd + time(0));
16+
rd *= 2;
17+
uniform_real_distribution<db> dist0(0, 1);
18+
now = (l + r) / 2, t = r - l;
19+
while (t > 1e-6)
20+
{
21+
uniform_real_distribution<db> dist(-t, t);
22+
db newx = now + dist(mt);
23+
newx = max(1. * l, min(1. * r, newx));
24+
db fnow = f(now), fnew = f(newx);
25+
db dt = (-fnew) - (-fnow);
26+
if (fnow < fnew || exp(-dt / t) > dist0(mt))
27+
{
28+
now = newx;
29+
}
30+
if (ans < fnew)
31+
{
32+
ans = fnew;
33+
}
34+
t *= 0.999;
35+
}
36+
for (ll i = 0; i < 1000; ++i) //在终温随机多次
37+
{ //优化效果不明显
38+
uniform_real_distribution<db> dist(-t, t);
39+
db newx = now + dist(mt);
40+
newx = max(1. * l, min(1. * r, newx));
41+
db fnow = f(now), fnew = f(newx);
42+
if (fnow < fnew)
43+
{
44+
now = newx;
45+
}
46+
if (ans < fnew)
47+
{
48+
ans = fnew;
49+
}
50+
}
51+
}
52+
signed main()
53+
{
54+
sc(a), sc(b), sc(c), sc(d), sc(e), sc(l), sc(r);
55+
for (ll i = 0; i < 20; ++i) //重要:多次退火
56+
{
57+
solve();
58+
}
59+
printf("%lf", ans);
60+
return 0;
61+
}

0 commit comments

Comments
 (0)