【洛谷】P2261 [CQOI2007] 余数求和 的题解

【洛谷】P2261 [CQOI2007] 余数求和 的题解

洛谷传送门

题解

这还是蓝题,这还是省选qaq

题目看着很简单,但是真的很考验思路,思路对了,代码不到 5 5 5 分钟写完。

刚开始做的时候还是一如既往,打了个暴力,成功获得了 40 40 40 的好成绩,T 了一堆,然后开始认真考虑数学做法。

刚开始还是打了个表,发现了对于每个 [ k n + 1 + 1 , n k ] [\frac{k}{n + 1}+1,\frac{n}{k}] [n+1k+1kn] 的区间,它们的公差都是 n n n。然后继续推算发现

a n s = ∑ n i = 1 k m o d    i ans = \sum_{n}^{i = 1} k \mod i ans=ni=1kmodi

= ∑ n i = 1 k − i × ⌊ k i ⌋ = \sum_{n}^{i = 1} k - i \times \lfloor \frac{k}{i} \rfloor =ni=1ki×ik

这样的话,直接用数论分块就可以解决:先使同一块的 k i \frac{k}{i} ik 相等,那么剩下的就是一个等差数列求和。时间复杂度 O ( n ) O(\sqrt{n}) O(n )

十年 OI 一场空,不开 long long 见祖宗!!!

代码

#include <bits/stdc++.h>
#define lowbit(x) x & (-x)
#define endl "\n"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
namespace fastIO {
	inline int read() {
		register int x = 0, f = 1;
		register char c = getchar();
		while (c < '0' || c > '9') {
			if(c == '-') f = -1;
			c = getchar();
		}
		while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
		return x * f;
	}
	inline void write(int x) {
		if(x < 0) putchar('-'), x = -x;
		if(x > 9) write(x / 10);
		putchar(x % 10 + '0');
		return;
	}
}
using namespace fastIO;
ll n, k;
int main() {
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> k;
    ll ans = n * k;
    for(ll l = 1, r; l <= n; l = r + 1) {
        if(k / l != 0) {
        	r = min(k / (k / l), n); 
		}
        else {
        	r = n;
		}
        ans -= (k / l) * (r - l + 1) * (l + r) / 2;
    }
    cout << ans << endl;
	return 0;
}
题目描述似乎缺失了关键信息,通常我会需要了解“P10780 食物”是什么具体的算法竞赛题目,它来自在线平台洛谷(Luogu),以及该题目的大致背景、条件和目标。洛谷食物(Food)可能是某种数据结构或算法问题,比如贪吃蛇、分配任务等。 然而,我可以给你提供一个通用的模板: **[洛谷 P10780 食物 - 题目解析]** 题目名称:P10780 食物(假设是关于食物分配或者饥饿游戏的问题) 链接:[插入实际题目链接] **背景:** 此题通常涉及动态规划或者搜索策略。场景可能是有n个参与者(选手或角色),每个都有特定的食物需求或者优先级,我们需要在有限的食物资源下合理分配。 **分析:** 1. **输入理解**:首先读入n个参与者的信息,包括每个人的需求量或优先级。 2. **状态定义**:可以定义dp[i][j]表示前i个人分配完成后剩余的食物能满足第j个人的最大程度。 3. **状态转移**:递推式可能涉及到选择当前人分配最多食物的版本,然后更新剩余的食物数。 4. **边界条件**:如果剩余食物不足以满足某人的需求,则考虑无法分配给他;如果没有食物,状态值设为0。 5. **优化策略**:可能需要对状态数组进行滚动更新,以减少空间复杂度。 **代码示例(伪代码或部分关键代码片段):** ```python # 假设函数分配_food(demand, remaining)计算分配给一个人后剩余的食物 def solve(foods): dp = [[0 for _ in range(max_demand + 1)] for _ in range(n)] dp = foods[:] # 从第一个到最后一个参与者处理 for i in range(1, n): for j in range(1, max_demand + 1): if dp[i-1][j] > 0: dp[i][j] = max(dp[i][j], dp[i-1][j] - foods[i]) dp[i][j] = max(dp[i][j], distribute_food_to(i, dp[i-1][j])) return dp[n-1][max_demand] ``` **相关问题--:** 1. 这道题是如何运用动态规划的? 2. 如果有优先级限制,应该如何调整代码? 3. 怎样设计搜索策略来解决类似问题?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值