Skip to content

Commit

Permalink
v1.0.2:增加和修改了若干内容,主要增添了部分随机化内容
Browse files Browse the repository at this point in the history
  • Loading branch information
lr580 committed Apr 26, 2022
1 parent 79136b9 commit fe229e2
Show file tree
Hide file tree
Showing 5 changed files with 390 additions and 68 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@

## 更新日志

- 22/04/19 - 22/04/22 (`v1.0.2`)

- 增加了KMP算法周期与border
- 删除了凸包一节无关多余内容
- 增加了另一种写法的C语言快读
- 修正了计算几何判断线段相交的错误方法
- 增改了随机化的程序语法、公式和爬山算法及模拟退火例题
- 重制了珂朵莉树参考模板
- 微增了博弈论理论内容

- 22/04/06 - 22/04/07 (`v1.0.1`)

- 增加了位运算一节少量内容
Expand Down
34 changes: 34 additions & 0 deletions code/hill_climbing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <bits/stdc++.h> //SCNUOJ1679 http://10.191.65.243:5000/p/1679
using namespace std;
typedef long long ll;
typedef double db;
ll p, a, b, q;
db k, t = 0.5, d, minx = 0.5, nowx = 0.5;
db f(db x) // assume k=1
{
return sqrt(p - a + x * x) + sqrt(p - b + (k - x) * (k - x));
}
signed main()
{
scanf("%lld%lld%lld%lld", &p, &a, &b, &q);
while (q--)
{
scanf("%lf", &k);
minx = nowx = k / 2;
t = k / 2;
while (t > 1e-6) // t是温度参数
{
db x1 = nowx + t;
db x2 = nowx - t;
db newx = f(x1) < f(x2) ? x1 : x2;
nowx = newx;
if (f(newx) < f(minx))
{
minx = newx;
}
t *= 0.9; // 降温系数
}
printf("%lf %lf\n", minx, (k - minx));
}
return 0;
}
72 changes: 72 additions & 0 deletions code/odt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include <bits/stdc++.h> //SCNUOJ1731 https://oj.socoding.cn/p/1731
using namespace std;
#define sc(x) scanf("%lld", &x)
typedef long long ll;
ll n;
struct node_t
{
ll l, r;
mutable ll v; // mutable使得const可变(set元素是const)
node_t(const ll &il, const ll &ir, const ll &iv) : l(il), r(ir), v(iv) {}
inline bool operator<(const node_t &o) const { return l < o.l; }
};
set<node_t> odt; //建立一棵珂朵莉树
auto split(ll x) //珂朵莉基操
{
if (x > n)
return odt.end();
auto it = --odt.upper_bound(node_t{x, 0, 0});
if (it->l == x)
return it;
ll l = it->l, r = it->r, v = it->v;
odt.erase(it);
odt.insert(node_t(l, x - 1, v));
return odt.insert(node_t(x, r, v)).first;
}
void assign(ll l, ll r, ll v) //区间赋值为v, 均摊O(loglogn)
{
auto itr = split(r + 1), itl = split(l);
odt.erase(itl, itr);
odt.insert(node_t(l, r, v));
}
void add(ll l, ll r, ll v) //区间增加v, 均摊O(loglogn)
{
auto itr = split(r + 1), itl = split(l);
for (; itl != itr; ++itl) //枚举每个子区间
{
itl->v = itl->v + v;
}
}
ll query(ll l, ll r) //区间查询, 均摊O(loglogn)
{
ll res = 0;
auto itr = split(r + 1), itl = split(l);
for (; itl != itr; ++itl)
{ // itl->l, itl->r, itl->v 是当前子区间的左右端点和值
res += (itl->r - itl->l + 1) * (itl->v);
}
return res;
}
signed main()
{
sc(n);
odt.insert({1, n, 1236895}); //初始化区间
ll m, cmd, l, r, x;
for (sc(m); m--;)
{
sc(cmd), sc(l), sc(r);
if (cmd == 1)
{
sc(x), assign(l, r, x);
}
else if (cmd == 2)
{
sc(x), add(l, r, x);
}
else
{
printf("%lld\n", query(l, r));
}
}
return 0;
}
61 changes: 61 additions & 0 deletions code/simulated_annealing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <bits/stdc++.h> //SCNUOJ1730 https://oj.socoding.cn/p/1730
using namespace std;
#define sc(x) scanf("%lld", &x)
typedef long long ll;
typedef double db;
ll a, b, c, d, e, l, r;
db x, t, now, mx, ans = -6;
db f(db x)
{
return sin(x / a) + sin(x / b) + sin(x / c) + sin(x / d) + sin(x / e);
}
void solve()
{
static ll rd = 1; //也可以用random_device生成种子
mt19937 mt(rd + time(0));
rd *= 2;
uniform_real_distribution<db> dist0(0, 1);
now = (l + r) / 2, t = r - l;
while (t > 1e-6)
{
uniform_real_distribution<db> dist(-t, t);
db newx = now + dist(mt);
newx = max(1. * l, min(1. * r, newx));
db fnow = f(now), fnew = f(newx);
db dt = (-fnew) - (-fnow);
if (fnow < fnew || exp(-dt / t) > dist0(mt))
{
now = newx;
}
if (ans < fnew)
{
ans = fnew;
}
t *= 0.999;
}
for (ll i = 0; i < 1000; ++i) //在终温随机多次
{ //优化效果不明显
uniform_real_distribution<db> dist(-t, t);
db newx = now + dist(mt);
newx = max(1. * l, min(1. * r, newx));
db fnow = f(now), fnew = f(newx);
if (fnow < fnew)
{
now = newx;
}
if (ans < fnew)
{
ans = fnew;
}
}
}
signed main()
{
sc(a), sc(b), sc(c), sc(d), sc(e), sc(l), sc(r);
for (ll i = 0; i < 20; ++i) //重要:多次退火
{
solve();
}
printf("%lf", ans);
return 0;
}
Loading

0 comments on commit fe229e2

Please sign in to comment.