2026-10-14 hetao1733837 的刷题记录

LGP17665 IO 2025 #3 LOIS

原题链接:IO 2025 #3 LOIS

分析

昨天晚上在操场跑步的时候 l y x lyx lyx 给我说了这个题。然后跑了 200 200 200 米之后我就会了。就是一些分讨。你做完了......


傻子 special judge🤬

正解

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 300005;
int n, k;
int a[N];
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> k;
    int cnt0 = 0;
    for (int i = 1; i <= n; i++){
        cin >> a[i];
        if (a[i] == 0) 
            cnt0++;
    }
    if (cnt0 != 0){
        cout << n + 1 << '\n';
        for (int i = 1; i <= n; i++) 
            cout << a[i] << ' ';
        cout << 0 << '\n';
        return 0;
    }
    int cnt2 = 0;
    for (int i = 1; i <= n; i++){
        if (a[i] == 2) 
            cnt2++;
    }
    if (cnt2 >= 2 && k >= 4){
        cout << n - 1 << '\n';
        int f = 0;
        for (int i = 1; i <= n; i++){
            if (a[i] == 2) {
                f++;
                if (f == 2) 
                    cout << 4 << ' ';
                if (f > 2) 
                    cout << 2 << ' ';
            } 
            else{
                cout << a[i] << ' ';
            }
        }
        cout << '\n';
        return 0;
    }
    sort(a + 1, a + n + 1);
    if (a[1] == a[n]){
        bool ok = false;
        for (int i = 2; i * i <= a[1]; i++){
            if (a[1] % i == 0) {
                int j = a[1] / i;
                cout << n + 1 + a[1] - i - j << '\n';
                cout << j << ' ' << i << ' ';
                for (int t = 1; t <= a[1] - i - j; t++){
                    cout << 1 << ' ';
                }
                for (int t = 2; t <= n; t++){
                    cout << a[t] << ' ';
                }
                cout << '\n';
                ok = true;
                break;
            }
        }
        if (!ok) 
            cout << -1 << '\n';
    } 
    else{
        cout << n << '\n';
        swap(a[1], a[n]);
        for (int i = 1; i <= n; i++){
            cout << a[i] << ' ';
        }
        cout << '\n';
    }
    return 0;
}

LGP2862 USACO06JAN Corral the Cows G

原题链接:USACO06JAN Corral the Cows G

分析

思考一下,那我直接二分边长,然后 n 2 n^2 n2 check?这个好像有点超时......那不如枚举三叶草数量然后算最小的边长。

哦,这个是不是真的可以写......呃,好像需要什么线段树之类的东西?慢慢想,别急。

不是,这个,我把所有的三叶草都排到 x x x 轴上,然后,枚举起点,二分出来第一个大于 C C C 的位置,然后,找出 y y y 的最大值,是不是做完了?对吧......那,直接开写吧......有点怵......加油,试一下嘛......

其实直接二分就行了。

正解

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1005, M = 10005;
int c, n;
struct node{
	int x, y;
}inp[N];
int sum[N][N];
vector<int> a;
bool check(int x){
	for (int i = 0, j = 1; j < (int)a.size(); j++){
		while (a[j] - a[i + 1] + 1 > x)
			i++;
		for (int k = 0, l = 1; l < (int)a.size(); l++){
			while (a[l] - a[k + 1] + 1 > x)
				k++;
			if (sum[j][l] - sum[i][l] - sum[j][k] + sum[i][k] >= c){
				return true;
			}
		}
	}
	return false;
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> c >> n;
	a.push_back(0);
	for (int i = 1; i <= n; i++){
		cin >> inp[i].x >> inp[i].y;
		a.push_back(inp[i].x);
		a.push_back(inp[i].y);
	}
	sort(a.begin(), a.end());
	a.erase(unique(a.begin(), a.end()), a.end());
	for (int i = 1; i <= n; i++){
		int pos1 = lower_bound(a.begin(), a.end(), inp[i].x) - a.begin();
		int pos2 = lower_bound(a.begin(), a.end(), inp[i].y) - a.begin();
		sum[pos1][pos2]++;
	}
	for (int i = 1; i < N; i++){
		for (int j = 1; j < N; j++){
			sum[i][j] += sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];
		}
	}
	int l = 1, r = 10000;
	while (l < r){
		int mid = (l + r) >> 1;
		if (check(mid))
			r = mid;
		else
			l = mid + 1;
	}
	cout << l;
}

LGP3201 HNOI2009 梦幻布丁

原题链接:HNOI2009 梦幻布丁

分析

如果真的是启发式合并的话......那不是特别难想吧......

呃,我拿 set 记录每个颜色的段,那么,对于合并,我们只需要判断是不是与合并的相互重合即可,然后,全局记录一个东西,做完了......怎么写代码呢?

我并不会写 merge 部分😭

找 A I AI AI 调一下......

正解

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100005, M = 1000005;
int n, m;
vector<int> pos[M];
int sz[M];
int rl[M];
int id[M]; 
int col[N];
int ans;
void merge(int cx, int cy, int tar){
    for (int p : pos[cx]) {
        if (p > 1 && rl[col[p - 1]] == tar) 
			ans--;
        if (p < n && rl[col[p + 1]] == tar) 
			ans--;
    }
    for (int p : pos[cx]){
        col[p] = cy;
        pos[cy].push_back(p);
    }
    sz[cy] += sz[cx];
    sz[cx] = 0;
    pos[cx].clear();
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i++){
        cin >> col[i];
        pos[col[i]].push_back(i);
        sz[col[i]]++;
    }
    for (int i = 1; i < M; i++){
        rl[i] = i;
        id[i] = i;
    }
    for (int i = 1; i <= n; i++){
        if (rl[col[i]] != rl[col[i - 1]]) 
			ans++;
    }
    for (int cs = 1, op, x, y; cs <= m; cs++){
        cin >> op;
        if (op == 1){
            cin >> x >> y;
            if (x == y) 
				continue;
            int cx = id[x], cy = id[y];
            if (cx == cy) 
				continue;
            if (sz[cx] > sz[cy]){
                swap(rl[cx], rl[cy]);
                swap(id[x], id[y]);
                swap(cx, cy);
            }
            merge(cx, cy, rl[cy]);
        }
        if (op == 2){
            cout << ans << '\n';
        }
    }
    return 0;
}

CF600E Lomsat gelral

原题链接:E. Lomsat gelral

分析

这个写一个树上启发式合并,每个点开一个 set 维护颜色个数和颜色编号,在每棵子树的根出合并,然后做完了。

别卡常了😭

正解

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100005;
int n;
int col[N];
vector<int> e[N];
int sz[N], son[N];
int cnt[N];
int mx, sum;
int ans[N];
void dfs1(int u, int fa){
    sz[u] = 1;
    for (auto v : e[u]){
        if (v == fa) 
            continue;
        dfs1(v, u);
        sz[u] += sz[v];
        if (sz[v] > sz[son[u]]) 
            son[u] = v;
    }
}
void add(int c, int val){
    if (val == 1){
        cnt[c]++;
        if (cnt[c] > mx){
            mx = cnt[c];
            sum = c;
        } 
        else if (cnt[c] == mx){
            sum += c;
        }
    } 
    else{
        cnt[c]--;
    }
}
void dfs_add(int u, int fa, int val){
    add(col[u], val);
    for (auto v : e[u]){
        if (v == fa) 
            continue;
        dfs_add(v, u, val);
    }
}
void dfs2(int u, int fa, int keep){
    for (auto v : e[u]){
        if (v == fa || v == son[u]) 
            continue;
        dfs2(v, u, 0);
    }
    if (son[u]){
        dfs2(son[u], u, 1);
    }
    for (auto v : e[u]){
        if (v == fa || v == son[u]) 
            continue;
        dfs_add(v, u, 1);
    }
    add(col[u], 1);
    ans[u] = sum;
    if (keep == 0){
        dfs_add(u, fa, -1);
        mx = 0;
        sum = 0;
    }
}
signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++){
        cin >> col[i];
    }
    for (int i = 1, u, v; i < n; i++){
        cin >> u >> v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    dfs1(1, 0);
    dfs2(1, 0, 1);
    for (int i = 1; i <= n; i++){
        cout << ans[i] << " ";
    }
    return 0;
}
相关推荐
罗斯8391 小时前
Datalog与安全分析
算法·安全·网络安全
浅念-2 小时前
动态规划:线性DP——多状态DP与子数组专题笔记
c++·笔记·算法·leetcode·职场和发展·动态规划·力扣
Data analyse4562 小时前
rrweb回放事件资源加载顺序重放校验
前端·人工智能·算法·机器学习·数据分析
昨夜见军贴06162 小时前
原始采样记录数字化落地,IACheck AI 报告文档审核 Agent 实现监测文档校验自动化
人工智能·算法·自动化
微学AI2 小时前
从历史曲线到提前预警:TimechoAI 的时序预测与业务落地实践
人工智能·算法
不会就选b3 小时前
算法日常・每日刷题--<动态规划>26
算法·动态规划
荆棘鸟智能3 小时前
虫情测报灯图像识别算法实践:小目标检测、粘连计数与飞虱细粒度分类
算法·目标检测·分类
爱读书的小胖3 小时前
LeetCode 27. 移除元素(C)解题分析
数据结构·算法
科技小E3 小时前
敏感数据不敢上云训练?本地大模型推理服务器DLTM私有化部署,让训练全程留在企业内网
大数据·算法·自动化