2025年4月月记

2025.4.1

现在我在学校上次去考了那个四川算法设计大赛,特别的简单,除了一道选择题没看到我的答案,其他的都轻松拿下,特别是有一道程序完善题,考的是Dijkstra的模版,我早就背下来了嘿嘿,就看复赛了,我是真的有点害怕OI模式,看不到我的分数我会很急,我的OI模式考的一般都挺差的,怕的就是每道题都有坑。。。每道题不仅考数学思维,还会考语文的阅读理解!!?我是真的会谢!今天班主任发威了,全班的学生都在颤抖,基本上"犯罪的学生"都被抓了。我是真的还流浃背了,主要是老师的气场太强了,我的寝室里有零食,就怕老师下一个点到的人是我。我们学校的主任都太逆天了,今天跑操时,主任跟发疯了一样,让我们停下搜我们身(说是看到了同学带卡片了,其实那个同学也给我看了他的卡片,嘿嘿)。我是真的无语了。。。

2025.4.4

今天是我妹妹的生日,但刚好我又要去考一场试,是去嘉祥锦江去考试了,就看能不能过了,如果能过那可太好了。但是

  1. 编程考试,满分400分,我只考了265,预计350。预计预实际之间的差距就是我OI模式的不熟悉导致的。第二题A了,第一题得了95!!第三题只有20分,第四题是50分。总结一下,第一题没达到预期,错误点为输出条件不清楚(就是没读题),第二道题达到了预期,第三道题没达到预期,错误点为按位或和按位与没有理解清楚,知识点不够熟练。第四题达到了预期,它是一道动态规划,但本人动态规划很差,所以只能用贪心骗了qwq。。。
  2. 主课考试,满分200分,实际分数未知。语文直接摆烂,好家伙都不会(还是会一些些的),数学应该还好,但有三道题没时间做,老师也说了,这就不是给我考满分的,所以我认为只要时间多一些我就能满分。
    综上,能过还是很悬的,如果上了,我也是很开心的啊。希望一切顺利吧!

2025.4.5

新的一天到来啦,我认为我的dp还是太差了,所以我需要好好练习呢。下午学习了并查集的新方法,有一些难度,但对我来说还是能接受,其实熟悉了做题套路与方法,还是很so easy的。晚上要考atcoder,不知道atcoder的难度如何,我有空肯定会整理整理的,要不就下周五吧,或者请看VCR

2025.4.6

我是真的分层图不懂啊,也不能说是不懂,只能说是不会分层。我在网上又找了些分层图讲解,只能说略知皮毛吧,现在我对分层图的主要看法就是:

  • 先造点,而点呢,可以通过题目中的具体变量进行组合。
  • 然后按照单/双向路来建图,有的时候是u -> v + n(仅有其中一种边),有的时候是u -> v(仅有其中一种边)。具体判断过程就是这道题是否有次数限制(一般是有的),但有些题有些抽象,他用分层图好做,但没有次数限制,比如说这道题,他是普通的最短路多了一个限制,就好像有一种背包题一样,除了体积,还有其他的限制。既然都这样说了,所以也是可以考虑dp的,到一个点后,看是到这个点更优还是不到。第二种做法就是分层图,这道题就可以用第二个条件进行分层(具体来说其实是编点)。
    既然说都说了,那么就来讲一下这道题吧。。。(题目地址已提供)

思路

首先看一手数据范围,非常安全,我们可以考虑分层,来达到第二个限制不用限制的目的,但该怎么建点呢?我们就可以考虑用第二个参数(也就是题目中的hi)来进行分点。最后跑一个最短路即可,没有什么难点,代码如下:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e3 * 201 * 2 + 10, INF = 0x3f3f3f3f3f3f3f3f;
struct Node{
	int x, w;
};
vector <Node> mp[N];
struct pq{
	int x, dis;
	bool operator<(const pq &A) const{
		return dis > A.dis;
	}
};
int n, m, k, st, ed, dis[N];
void Dijkstra(int s){
	priority_queue <pq> q;
	q.push({s, 0});
	memset(dis, 0x3f, sizeof dis);
	dis[s] = 0;
	while(!q.empty()){
		pq t = q.top(); q.pop();
		int x = t.x, d = t.dis;
		if(d != dis[x]) continue;
		for(auto nxt : mp[x]){
			int y = nxt.x, w = nxt.w;
			if(dis[x] + w < dis[y]){
				dis[y] = dis[x] + w;
				q.push({y, dis[y]});
			}
		}
	}
}

signed main(){
	cin >> k >> n >> m;
	while(m --){
		int u, v, w1, w2; cin >> u >> v >> w1 >> w2;
		for(int i = 0; i < k; i++){
			mp[u + i * n].push_back({v + i * n + w2 * n, w1});
			mp[v + i * n].push_back({u + i * n + w2 * n, w1});
		}
	}
	cin >> st >> ed;
	Dijkstra(st);
	int ans = INF;
	for(int i = 0; i < k; i++) ans = min(ans, dis[ed + i * n]);
	cout << (ans >= INF ? -1 : ans) << "\n";
	return 0;
}

2025.4.12

转眼间一周就过去了,今天我看了一下2024年 CSP-S 的真题,第一题还好,做法就是装箱+求最大值,为什么这么做呢?啊哈哈,我也不知道,我也不想问如果我们对a数组进行排序,那么 a1 <= a2 <= a3 <= ... <= an ,然后呢我们能知道,一个怪兽它去打的那个怪兽的防御力和这个怪兽的攻击力接近,这就是最优的。那么最终活下来的必然是"等级最高的"(也就是攻击力最高的)+ 人数最多的 - x(x为打"人数最多的"的那些人)。而细心就能发现这个算式的和就是上面说的人最多的那个数量,代码挺简单的就不放了。

第二题就开始有点懵了,但还是有思路,就是把加速度分为两个个部分:

  • \(a > 0\), 在这个情况下,我们可以用二分求出左端点的位置,但想要求解,我们不难发现基准值又不一样,所以我们又分为两种情况:1. 原本就超速,那么左端点必然是\({\large p}{\small j} \geq {\large d}{\small i}\)的最小\(j\)。2.需要行驶一段路程才能把速度加超速,那么我们可以用题目中的算式得出他的左端点的表达式为\({\large p}{\small j} > ({\large d}{\small i} + \frac{V^2 - {\large v}{\small i}^2}{2 * {\large a}{\small i}})\)的最小\(j\)。
    因为题目保证速度是单调递增的(此情况下),所以,右端点一定是m。
  • \(a \leq 0\),因为这个情况下的速度是单调递减的,所以如果初速本身就小于\(V\),那么一定不超速,否则分别二分出他的左端点与右端点,我们一个一个分开看:
  1. 左端点,跟上面的(\(a>0\))的第一种情况相似,就是满足\({\large p}{\small j} \geq {\large d}{\small i}\)的最小\(j\)。2.右端点,我们又可以根据二分(枚举时间),快速计算出路程,这里的二分条件为\({\large v}{\small 1} > V\)。
    思路就是这样,我们在处理一下精度,调一下细节,代码就是这样的:
cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int T, p[N], cnt, d[N], v[N], a[N];
bool vis[N];
struct qj{
    int l, r;
}q[N];
bool cmp(qj x, qj y){
    if(x.l != y.l) return x.l < y.l;
    return x.r > y.r;
}
void solve(){
    int n, m, L, V; scanf("%d %d %d %d", &n, &m, &L, &V);
    cnt = 0;
	memset(vis, 0, sizeof vis);
    for(int i = 1; i <= n; i++) scanf("%d %d %d", &d[i], &v[i], &a[i]);
    for(int i = 1; i <= m; i++) scanf("%d", &p[i]);
    int idx = 0;
    for(int i = 1; i <= n; i++){
        if(a[i] <= 0 && v[i] <= V) continue;
        if(a[i] > 0){
            int ans = 0;
            if(v[i] > V) ans = d[i] - 1;
            else ans = d[i] + (V * V - v[i] * v[i]) / (2 * a[i]);
            int id = upper_bound(p + 1, p + m + 1, ans) - p;
            if(id > m) continue;
            q[++ idx].l = id;
            q[idx].r = m;
        }
        else{
            int id = lower_bound(p + 1, p + m + 1, d[i]) - p;
            if(id > m) continue;
            int l = id, r = m, res = 0;
            while(l <= r){
                int mid = l + r >> 1;
                double v1 = sqrt(v[i] * v[i] * 1.0 + 2.0 * a[i] * (p[mid] - d[i]));
                if(v1 > V) res = mid, l = mid + 1;
                else r = mid - 1;
            }
            if(res < id) continue;
            q[++ idx].l = id, q[idx].r = res;
        }
    }
    sort(q + 1, q + idx + 1, cmp);
    int ed = 2e9;
    for(int i = idx; i >= 1; i--){
        if(ed <= q[i].r) vis[i] = true;
        ed = min(ed, q[i].r);
    }
    ed = 0;
    for(int i = 1; i <= idx; i++){
        if(vis[i]) continue;
        if(ed < q[i].l){
            cnt ++;
            ed = q[i].r;
        }
    }
    cout << idx << " " << m - cnt << "\n";
}

int main(){
    cin >> T;
    while(T --) solve();
    return 0;
}

第三题和第四题就不看了,个人觉得挺难的。我不会

2025.4.18

今天我看了一下C++的题库,不看不知道,一看吓一跳,突然多出了两个题单,一个题单50道题。。。通过题单的名字,能够看出这是CSP复赛的冲刺题。J组的还好,A了几道,S组的还没看。

今天J组学的是树结构,没什么难度,六级备考时也学了。

突然发现J组考的数学好变态啊,第一题都会考一元二次方程的吗?我只是简单的接触过,如果正要再考场上写,那可能有点悬。上次J组210分遗憾落榜,这次别给我整些《疑难杂症》就行了。

2025.4.19

我好像昨天又忘了洛谷上的比赛,我怎么每次都报名了,每次都忘了呢???不知道会不会扣我估值或者等级分。要扣了我直接一辈子白打哭晕在厕所(bushi)。

我早上又打了高老师上海月赛,前四题只要不犯什么低级错误就好,第五题我随便写了一种解法,要不是现在没有找到反例,否则我早就崩了。第五题应该是道大模拟,但我不能确定我又没有什么细节写错了。。。祝好吧(对我)。我真是越想越不对劲,那只能不想了,要是把反例想出来了,那我不炸了吗?

今天学习了生成树进阶,现在的题也只是看得懂了,代码好写,但前提是你得知道代码应该这么写。。。而且还有一些好玩 的题,代码也难写的要死,看着别人信手拈来的AC我直接就是汗流浃背了呀。

晚上又考了atcoder,第四题比之前的第四题更难一些,但还是A了好吧。其实就是找规律,他问有多少对相交的线,那我们就把他转化成总共的线段组合减去平行的线,但想要计算平行的线还是有难度的,不过抓住规律即可。我这次可以找个时间给atcoder录个视频。最近状态不错啊。第五题是个动态规划,比较复杂,有点费脑子,明天在想吧。拜拜~

2025.4.20

今天早上去参加了温江区的区运会,我的项目是60米和100米,60米和100米都是第21名。。。一共应该有个八十九十人吧。总结:60米后面身体没挺起来,重心也太靠前了差点栽了,没跑好,100米还好,至少是小组第一。回来后终于把昨天的atcoder给补起了,错误点说实话没找到,改了一下代码风格就出来了~~(具体来说的话,大概可能是下标的问题吧...)

下午还打了小明月赛的div2,难度还好,但我的情况不是很乐观,前三题不出意外的话应该出不了意外,第四题和第五题打的是暴力,第四题我一直以为我能想出正解,结果却耗费了我大量的时间,导致我第五题没提交上,搞不好我第五题的那个方法是正解呢?哎,不说了,一说全是泪。明天又要去上学,好心情全没了。最讨厌上学了,学校里的老师没几个善茬,全都是玩"大家一起来找茬"长大的。

晚上我准备录个视频,再做点J组的必刷题,就OK了。希望明天是个好日子。

2025.4.22

今天是星期二,我能回来主要是因为今天出来考了一场试,是数学。题目总体难度不难除了最后一题,都会做,就看错没错,错了的基本就是粗心了,最后一道题好像是给你三杯溶液,第一杯溶液有溶质A和溶质B,第二杯有溶质B和溶质C,第三杯有溶质A和溶质C,第一、二、三杯的溶质比分别是3:2、3:5、5:2。我们按照一定的比例调出了一杯包含溶质A、B、C的溶液,溶质的比为3:5:2,问:如果第三杯加了24千克,那么第一杯和第二杯各加了几千克。这道题我是没什么思路,只知道他是比例解浓度问题说了句废话。

本来今天晚上要考语文的(在学校),但因为我出来考了数学,所以成功逃过了一劫,听说语文有六面,听着就不想考。其实我之前语文和数学是差不多的(差),但在外面学了数学后,数学就抛弃了语文,跑到了前面去,导致现在我要为语文的丢分买单。。。

2025.4.25

可恶的调休,让这周只休息了一天多,你知道这对一个xxs的伤害有多大吗?今天学的还是树,只是变难了一些些,对我来说难度还是比较正常的,主要的只是点就是树上递推,作业有两道题都很有意思,第一道是这个,第二题是这个,这两道题按思路来说第一题会难不少,第二题优化难死个人,都调了老久了(主要还是第二题调得多,因为优化,懂吧?)。S组学了强联通分量,难度还是有的,老师说这个知识点很重要,对我来说有点难,但意思还是理解了的。作业都做了,但难度是真的感人。

什么?atcoder的比赛调时间了?em...那只能补题了,希望atcoder难度不难,昨晚做了个梦,梦到我CSP-J只考了200分,第二题的dfs没优化,直接卡成了20分,分数线是210分。。。心态炸了。。。

转眼间4月就快过去了,可能这是我四月写月记的最后一天了吧。那我们就五月再见吧~~~