2024-7-9 ~ 10-12 记录
- 7-9
我觉得 ... 应该重开个档来写了,算作是暑假专题?
这次暑假的目标就是把 dp 搞完,但是我图论还没结束?还一些树上问题,tarjan、负环、查分约束、拓扑排序、欧拉路、2-sat(仅仅是书上提到的)
7月份能搞完吗?尽力吧。
早上 Minimum spanning tree for each edge,很典的 lca 维护路径上最大值
这里总结一些吧:
倍增 lca 可以在倍增的同时维护树上简单路径的 边权最大值、最小值,记录、修改覆盖信息(差分),还有找中点之类的
求直径同时要用 lca 维护两点间距离,还行吧
主要是 P3304 [SDOI2013] 直径 这题虽然评绿,但比上边这两道蓝的难得多,就是求直径的必经边
码了 160 多行,还没调出来 ...
还有一个无意遇到的 八倍经验 ?!必须 mark 一下 qwq
- 7-10~11(3题)
P2195 HXY造公园 这题卡我一晚上,今天中午过来把 T 了两个点的两遍 dfs 换成 树形 dp 就过了?!这俩算法的本质都是 dfs,复杂度不都是 O(n) 吗 ...
- 7-12(1题)
两道毒瘤直径题 P5536 【XR-3】核心城市、P3304 [SDOI2013] 直径
哎,调程序好烦啊,md,又热
不过明天就放暑假咯,欧耶 (也要上强度了
- 7-17
发现自己真的好飞舞啊,学个基环树找直径,又要去学环形 dp,单调队列优化,真的是啥都不懂吗 ...(╯▽╰)
- 7-24
好多拓扑排序都跟 dp 结合啊,或者说 dp 套了拓扑序的预处理(恼
- 7-30
我今天真的,真的是tmd吃了史,
https://www.luogu.com.cn/problem/P3225 这道题目调了半年,#1、#2 的测试点在本地都能过,最后没办法发个帖,别人跟我说是厌氧,好好好,开个 o2 还搞出 ub 了是吧
https://www.luogu.com.cn/problem/UVA12167 这也是个板子,md,结果顺手貌似又搞出来 ub,我靠,一个下午,搞出两个 ub,真他娘的是个天才。。。整个下午的时间都耗在这两个煞笔 ub 上了,,,
- 8-1
dp 启动!
- 8-3
越起越早了,今天 6:36 就打开电脑了 haha
这两天的比赛安排(好多啊)
8-3:
14:30~18:00 【LGR-195-Div.3】洛谷基础赛 #14 & Flanksy Round I
20:00~21:40 Toyota Programming Contest 2024#8(AtCoder Beginner Contest 365)
8-4:
13:30~17:00 【MX-J2】梦熊周赛 · 入门组 2(同步赛)
20:00~22:00 AtCoder Regular Contest 181
22:35~00:35(+1) Codeforces Round 963 (Div. 2)
- 8-15
今天上洛谷,突然发现cf的爬虫挂了,呜呜,那我还怎么水题数(qwq
mark:
Codeforces Round 965 (Div. 2)
EPIC Institute of Technology Round August 2024 (Div. 1 + Div. 2)
https://www.luogu.com.cn/problem/CF607B
https://www.luogu.com.cn/problem/CF1132F
https://www.luogu.com.cn/problem/CF1092F
https://www.luogu.com.cn/problem/CF1077F2
https://www.luogu.com.cn/problem/CF1175E
updated during 10-13~26
https://www.luogu.com.cn/problem/CF280B
https://www.luogu.com.cn/problem/CF1407D
https://www.luogu.com.cn/problem/CF915E
蛙趣,这个代码真的美,可能这也是dp魅力所在之一吧,方程和代码简洁而巧妙,好爽。。。(其实会写的题就爽,不会的话.......
特别是在 dec-c++ 上用 Courier New 显示,突然理解为什么有人喜欢写大写字母变量了
code
#include <bits/stdc++.h>
#define re register int
#define max(x, y) (x > y ? x : y)
#define min(x, y) (x < y ? x : y)
using namespace std;
const int N = 110, inf = 0x3f3f3f3f;
char ch[N];
int n, w[N], res = -inf;
int f[N][N], g[N][N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n;
for (re i = 1; i <= n; i ++)
{
cin >> ch[i] >> w[i];
ch[i + n] = ch[i], w[i + n] = w[i];
}
memset(f, -0x3f, sizeof(f));
memset(g, 0x3f, sizeof(g));
for (re i = 1; i <= n * 2; i ++) f[i][i] = g[i][i] = w[i];
for (re len = 1; len <= n; len ++)
for (re l = 1; l + len - 1 <= n * 2; l ++)
{
int r = l + len - 1;
for (re k = l; k < r; k ++)
{
char op = ch[k + 1];
int maxL = f[l][k], minL = g[l][k];
int maxR = f[k + 1][r], minR = g[k + 1][r];
if (op == 't')
{
f[l][r] = max(f[l][r], maxL + maxR);
g[l][r] = min(g[l][r], minL + minR);
}
else
{
int a = minL * minR, b = minL * maxR, c = maxL * minR, d = maxL * maxR;
f[l][r] = max(f[l][r], max(max(a, b), max(c, d)));
g[l][r] = min(g[l][r], min(min(a, b), min(c, d)));
}
}
}
for (re i = 1; i <= n; i ++) res = max(res, f[i][i + n - 1]);
cout << res << '\n';
for (re i = 1; i <= n; i ++)
if (f[i][i + n - 1] == res) cout << i << ' ';
return 0;
}
- 8-16
明天开学了(呜呜呜,好像是读到 25 号,八天时间
计划尽量把状压、树形 dp(顺便把树形依赖背包学了)搞掉
剩下就是各种的 dp 优化技巧,到 9-21 初赛还有三个星期多六天的时间,希望能结束 dp
哦对了,从 9-1 到 11-30 联赛,巨资买了luogu的noip模拟赛,每周天的 14:00 - 18:00,夹杂着搞掉
然后到 10-26 复赛有五个星期,再到 11-30 联赛也是五个星期,数据结构、字符串、搜索 和一些杂项应该搞得完(数学......谔谔)
- 8-21
下晚二的时候,正常我要从前门背着书包去机房,看完刚贴的联考通知,推开门,看见她刚好就站在门口,看着我,不知道是刚好路过,还是我觉得她好像一直就是站在那......
一下子我慌了神,想要叫一下她名字打个招呼,不过硬是太着急就没说出口......走远了,不知道为什么,自那段时间以后,过了这么久,碰见她还是很紧张,心里砰砰地跳个不停......
希望不是我想的那样,应就是碰巧遇到罢。时间错了,我还有更重要的事情,我这次真的必须紧紧抓住它
- 8-22
日了狗了,树形dp怎么这么难,不会状态设计啊(
- 8-23
崩溃了,一道题不会做,只能看题解,唉唉
- 9-2
前缀和优化 dp 简单题我都觉得好难,,,废了废了,这还玩毛啊 ┭┮﹏┭┮
- 9-4
怎么感觉两节晚自习有点扛不住,后面脑袋晕晕的(恼,可能是因为明天开学考吧,没复习一点
- 9-9
单调队列优化搞不懂怎么办......迷茫
初赛前还是不学新算法了,先把比赛、题单补掉,学算法效率太低了,感觉这个比赛时间也没协调好,周日早上没心思打比赛,下午又要赶火车来学校没时间,前两次的模拟赛也就基本上没打什么,浪费掉了,400块钱啊
想了想,下午必须早点来学校,三点左右就到机房来,认真搞三个小时
初赛应该随便搞搞就过吧
想想啊,还有 数据结构、字符串、数学 这三大块,搜索、动态规划(特别是) 也都好像没学好
什么鬼,atcoder 在维护 ......
https://www.luogu.com.cn/problem/AT_abc287_h
- 9-11
今天晚上也是自己终于终于终于 ...... 做出一道单调队列优化dp了 P3572 [POI2014] PTA-Little Bird,爽,明天策略直接开写
单调队列虽然说是很板,一般就是做滑动窗口类的题目用,但有一些额外的细节,很恶心,不能死记,要理解内在含义,要不然考场乱写瞎猜 就 ......心态爆炸,gg ......
比如 h,t 初值要不要放哨兵,决策 与 队尾出队、入队 的先后(当然队头要出队了一定先出队)
- 9-21
csp-s 估分 52.5,应该能过吧 ...... 好像,为什么有泄题啊喂
那么也该规划一下了(东西好多,老是有时候不知道从哪里搞起,就老是要先计划
堆 -> 并查集 -> st表 -> hash -> 树状数组 -> 线段树 -> 分块
九月份搞到树状数组差不多了
- 9-22
和朋友突来兴致,全力跑了一圈 300m,不是,58s ...... 这运动会 800m 不得被拉爆了,名次不重要,主要是有点丢人 。。。
我靠,现在肚子还有点隐隐作痛
- 9-23
ccf 实际改出来 62 ?差这么多吗
- 9-25
一遍过一道码量比较大的 st表练习题 P9704 「TFOI R1」Tree Home,爽 qwq
吉吉的歌还蛮不错的
code
#include <bits/stdc++.h>
#define re register int
using namespace std;
const int N = 2e5 + 10, logN = 50;
struct Edge
{
int to, w, next;
}e[N << 1];
int top, h[N];
int n, q, a[N], dist[N];
int add[N][logN][2], sub[N][logN][2], lg[N]; // 0 - max, 1 = min
inline void build(int x, int y, int w)
{
e[++ top] = (Edge){y, w, h[x]};
h[x] = top;
}
void dfs(int u, int fa)
{
for (re i = h[u]; i; i = e[i].next)
{
int v = e[i].to, w = e[i].w;
if (v == fa) continue;
dist[v] = dist[u] + w;
dfs(v, u);
}
}
inline void init()
{
lg[0] = -1;
for (re i = 1; i <= n; i ++)
{
lg[i] = lg[i / 2] + 1;
add[i][0][0] = add[i][0][1] = pow(dist[i], 3) + a[i];
sub[i][0][0] = sub[i][0][1] = pow(dist[i], 3) - a[i];
}
for (re j = 1; j <= lg[n]; j ++)
for (re i = 1; i + (1 << j) - 1 <= n; i ++)
{
add[i][j][0] = max(add[i][j - 1][0], add[i + (1 << (j - 1))][j - 1][0]);
add[i][j][1] = min(add[i][j - 1][1], add[i + (1 << (j - 1))][j - 1][1]);
sub[i][j][0] = max(sub[i][j - 1][0], sub[i + (1 << (j - 1))][j - 1][0]);
sub[i][j][1] = min(sub[i][j - 1][1], sub[i + (1 << (j - 1))][j - 1][1]);
}
}
inline int solve_add(int l, int r, int type)
{
int k = lg[r - l + 1];
if (type == 0)
return max(add[l][k][0], add[r - (1 << k) + 1][k][0]);
else
return min(add[l][k][1], add[r - (1 << k) + 1][k][1]);
}
inline int solve_sub(int l, int r, int type)
{
int k = lg[r - l + 1];
if (type == 0)
return max(sub[l][k][0], sub[r - (1 << k) + 1][k][0]);
else
return min(sub[l][k][1], sub[r - (1 << k) + 1][k][1]);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> q;
for (re i = 1; i <= n; i ++) cin >> a[i];
for (re i = 1; i < n; i ++)
{
int x, y, z; cin >> x >> y >> z;
build(x, y, z), build(y, x, z);
}
dfs(1, 0);
// for (re i = 1; i <= n; i ++)
// cout << i << ' ' << dist[i] << '\n';
init();
while (q --)
{
int Lp, Rp, Lq, Rq; cin >> Lp >> Rp >> Lq >> Rq;
int res = 0;
res = max(res, solve_add(Lp, Rp, 0) - solve_add(Lq, Rq, 1));
res = max(res, solve_sub(Lp, Rp, 0) - solve_sub(Lq, Rq, 1));
res = max(res, solve_sub(Lq, Rq, 0) - solve_sub(Lp, Rp, 1));
res = max(res, solve_add(Lq, Rq, 0) - solve_add(Lp, Rp, 1));
cout << res << '\n';
}
return 0;
}
哦对了,2024 年 9 月 25 日 中午完成的这道题刚好也是我在洛谷上通过的第 1000 道题,通过 1k 祭 ......
(虽然现在感觉这种行为很 xxs,但还是,生活总要有些仪式感咯
- 9-29
树状数组学傻了,艹
- 10-4
难得国庆节四天假,家里人来我们这玩 。。。淦
一场模拟赛、三节课冲掉了,现在又要挤时间补呦
那么,直接开搞 线段树 !!!一个星期,能学多少学多少
- 10-7
今天一遍过了 P1558 色板游戏,虽然是一到很典型的状态压缩,然后用线段树维护区间按位或,
但是敲板子也是一件很快乐的事,su fu~
code
#include <bits/stdc++.h>
#define re register int
#define lp p << 1
#define rp p << 1 | 1
using namespace std;
const int N = 1e5 + 10;
struct Tree
{
int l, r, num, tag;
}t[N << 2];
int n, m, q;
inline void push_up(int p)
{
t[p].num = t[lp].num | t[rp].num;
}
inline void push_down(int p)
{
if (t[p].tag)
{
t[lp].num = t[rp].num = (1 << t[p].tag);
t[lp].tag = t[rp].tag = t[p].tag;
t[p].tag = 0;
}
}
inline void build(int p, int l, int r)
{
t[p].l = l, t[p].r = r;
if (l == r)
{
t[p].num = (1 << 1);
return;
}
int mid = (l + r) >> 1;
build(lp, l, mid);
build(rp, mid + 1, r);
push_up(p);
}
inline void update(int p, int l, int r, int k)
{
if (l <= t[p].l && t[p].r <= r)
{
t[p].num = (1 << k);
t[p].tag = k;
return;
}
push_down(p);
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid) update(lp, l, r, k);
if (r > mid) update(rp, l, r, k);
push_up(p);
}
inline int query(int p, int l, int r)
{
if (l <= t[p].l && t[p].r <= r) return t[p].num;
push_down(p);
int res = 0;
int mid = (t[p].l + t[p].r) >> 1;
if (l <= mid) res |= query(lp, l, r);
if (r > mid) res |= query(rp, l, r);
return res;
}
inline void print(int k)
{
int cnt = 0;
while (k)
{
if (k & 1) cnt ++;
k >>= 1;
}
cout << cnt << '\n';
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m >> q;
build(1, 1, n);
while (q --)
{
char c; cin >> c;
if (c == 'C')
{
int x, y, z; cin >> x >> y >> z;
if (x > y) swap(x, y);
update(1, x, y , z);
}
else
{
int x, y; cin >> x >> y;
if (x > y) swap(x, y);
int res_num = query(1, x, y);
print(res_num);
}
}
return 0;
}
又翻了翻之前的事,忘记记录上次运动会的成绩了,(居然过了这么久。。。)
上次运动会 800m,有史以来我跑过最快的一次了,我自己的表计 显示的是 2min51s(误差上下浮动 1s)
- 10-8
这题 P1471 方差,,,一顿猛做,史山代码,信仰交一发居然有 40pts qwq
code
#include <bits/stdc++.h>
#define re register int
#define lp p << 1
#define rp p << 1 | 1
using namespace std;
const int N = 1e5 + 10;
struct Tree
{
int l, r;
double sum, tag;
}t1[N << 2], t2[N << 2];
int n, q;
double a[N];
inline void push_up(int p)
{
t1[p].sum = t1[lp].sum + t1[rp].sum;
t2[p].sum = t2[lp].sum + t2[rp].sum;
}
inline void push_down(int p)
{
if (t1[p].tag)
{
t1[lp].sum += (t1[lp].r - t1[lp].l + 1) * t1[p].tag;
t1[rp].sum += (t1[rp].r - t1[rp].l + 1) * t1[p].tag;
t1[lp].tag += t1[p].tag;
t1[rp].tag += t1[p].tag;
t1[p].tag = 0;
}
if (t2[p].tag)
{
t2[lp].sum += 2 * t2[p].tag * t1[lp].sum + (t2[lp].r - t2[lp].l + 1) * t2[p].tag * t2[p].tag;
t2[rp].sum += 2 * t2[p].tag * t1[rp].sum + (t2[rp].r - t2[rp].l + 1) * t2[p].tag * t2[p].tag;
t2[lp].tag += t2[p].tag;
t2[rp].tag += t2[p].tag;
t2[p].tag = 0;
}
}
inline void build(int p, int l, int r)
{
t1[p].l = t2[p].l = l;
t1[p].r = t2[p].r = r;
if (l == r)
{
t1[p].sum = a[l];
t2[p].sum = a[l] * a[l];
return;
}
int mid = (l + r) >> 1;
build(lp, l, mid);
build(rp, mid + 1, r);
push_up(p);
}
inline void update(int p, int l, int r, double k, int type)
{
int lg = (type == 1 ? t1[p].l : t2[p].l);
int rg = (type == 1 ? t1[p].r : t2[p].r);
if (l <= lg && rg <= r)
{
if (type == 1)
{
t1[p].sum += (t1[p].r - t1[p].l + 1) * k;
t1[p].tag += k;
}
else
{
t2[p].sum += 2 * k * t1[p].sum + (t2[p].r - t2[p].l + 1) * k * k;
t2[p].tag += k;
}
return;
}
push_down(p);
int mid = (lg + rg) >> 1;
if (l <= mid) update(lp, l, r, k, type);
if (r > mid) update(rp, l, r, k, type);
push_up(p);
}
inline double query(int p, int l, int r, int type)
{
int lg = (type == 1 ? t1[p].l : t2[p].l);
int rg = (type == 1 ? t1[p].r : t2[p].r);
if (l <= lg && rg <= r) return (type == 1 ? t1[p].sum : t2[p].sum);
push_down(p);
double res = 0;
int mid = (lg + rg) >> 1;
if (l <= mid) res += query(lp, l, r, type);
if (r > mid) res += query(rp, l, r, type);
return res;
}
int main()
{
scanf("%d %d", &n, &q);
for (re i = 1; i <= n; i ++) scanf("%lf", &a[i]);
build(1, 1, n);
while (q --)
{
int op, x, y; scanf("%d %d %d", &op, &x, &y);
if (op == 1)
{
double k; scanf("%lf", &k);
update(1, x, y, k, 1);
update(1, x, y, k, 2);
}
else if (op == 2)
{
double res = query(1, x, y, 1) / (double)(y - x + 1);
printf("%.4lf\n", res);
}
else
{
double res2 = query(1, x, y, 2);
double res1 = query(1, x, y, 1);
double w = res1 / (double)(y - x + 1);
double ans = (res2 - 2 * w * res1 + (double)(y - x + 1) * w * w) / (double)(y - x + 1);
printf("%.4lf\n", ans);
}
}
return 0;
}
- 10-9
扫描线算是这辈子都学不会了。。。

浙公网安备 33010602011771号