1462E2 - Close Tuples (hard version)(组合数)

博客介绍了一道题的解题思路,先对数组排序,算出每个数的贡献,通过二分找到可选数个数,根据个数判断贡献值。在求组合数的模问题时,不能直接对相除的数分别取模再除,需用逆元和费马小定理转换成乘法,还给出了参考博客和板子链接。

题目

思路:先对数组排序,然后算出每个数的贡献,先从第一个数开始找到第一个大于它的值+k的数(二分),下表差即为可选的构成m个数元组的可选数的个数s,如果s<m贡献0,如果s>=m,贡献为从s-1个数中选出m-1个数的方法数(已经选了一个数)。但求组合数的模问题,不可以对两个相除的数先分别取模再除,故需要用到逆元和费马小定理先转换成乘法。不懂知道的可参考此篇博客https://www.cnblogs.com/liziran/p/6804803.html

#include<iostream>
#include<algorithm>
#include<cmath>
#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const int Max = 1e6 + 5;
ll lst[Max], x[Max];
const int Mod = 1e9 + 7;

ll qpow(ll a, ll b) {
	ll ans = 1, base = a;
	while (b) {
		if (b & 1) ans = ans * base % Mod;
		base = base * base % Mod;
		b >>= 1;
	}
	return ans;
}

int main()
{
	FAST;int t;cin >> t;
	x[0] = 1;
	for (int i = 1;i <= 2e5 + 5;i++)x[i] = (x[i - 1] * i) % Mod;
	while (t--)
	{
		ll n, m, k,sum=0;cin >> n >> m >> k;
		for (int i = 1;i <= n;i++)cin >> lst[i];
		sort(lst + 1, lst + 1 + n);
		for (int i = 1;i <= n;i++)
		{
			int l = upper_bound(lst + i, lst + 1 + n, lst[i] + k) - lst;
			int len = l - i;
			if (len < m)continue;
			sum = (sum + x[len - 1] * qpow(x[m - 1], Mod - 2) % Mod * qpow(x[len - m], Mod-2) % Mod)%Mod;
		}
		cout << sum << endl;
	}
}

当然直接用板子也是很爽的,板子链接

#include<iostream>
#include<algorithm>
#include<cmath>
#define FAST ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
const int Max = 1e6 + 5;
ll lst[Max], x[Max];
const int Mod = 1e9 + 7;

ll f[Max];
ll qpow(ll a, ll b) {
	ll ans = 1, base = a;
	while (b) {
		if (b & 1) ans = ans * base % Mod;
		base = base * base % Mod;
		b >>= 1;
	}
	return ans;
}
void init() {
	f[0] = 1;
	for (int i = 1;i <= 2e5;i++) {
		f[i] = f[i - 1] * i % Mod;
	}
}
ll cal(ll n, ll m) {
	if (n < m) return 0;
	return 1ll * f[n] * qpow(f[m], Mod - 2) % Mod * qpow(f[n - m], Mod - 2) % Mod;
}


int main()
{
	FAST;int t;cin >> t;
	init();
	while (t--)
	{
		ll n, m, k,sum=0;cin >> n >> m >> k;
		for (int i = 1;i <= n;i++)cin >> lst[i];
		sort(lst + 1, lst + 1 + n);
		for (int i = 1;i <= n;i++)
		{
			int l = upper_bound(lst + i, lst + 1 + n, lst[i] + k) - lst;
			int len = l - i;
			if (len < m)continue;
			sum += cal(len - 1, m - 1);
			sum%= Mod;
		}
		cout << sum << endl;
	}
}

这个错误信息表明你正在尝试将一个不正确的元素(在这个例子中是一个字符串 `'6'`)添加到一个字段列表或字典中。在Python中,通常当你使用框架如Django时,字段元素需要是2元组或3元组的形式,例如 `('value', 'display_name')` 或 `('value', 'display_name', additional_info)`。 如果你看到这个错误,可能是因为你在定义字段时传递了一个不符合要求的值。下面是一些示例代码和解释。 ### 示例代码 假设你在使用Django定义模型的 `choices` 参数: ```python class MyModel(models.Model): # 错误示例:这里的 '6' 不符合 2- 或 3-tuple 的要求 STATUS_CHOICES = [ '6', # 这里应该是一个元组,而不是单独的字符串 ('1', 'Active'), ('2', 'Inactive'), ] status = models.CharField( max_length=1, choices=STATUS_CHOICES, default='1', ) ``` ### 正确的写法 你需要确保所有的选项都是2元组或3元组: ```python class MyModel(models.Model): STATUS_CHOICES = [ ('6', 'Unknown'), # 确保每个元素都是一个元组 ('1', 'Active'), ('2', 'Inactive'), ] status = models.CharField( max_length=1, choices=STATUS_CHOICES, default='1', ) ``` ### 解释 - 在Django中,`choices` 参数需要是一个包含2元组或3元组的列表。每个元组的第一个元素是存储在数据库中的值,第二个元素是人类可读的显示名称。 - 如果你传递了一个不是元组的值(如字符串 `'6'`),就会引发这个错误。 ### 相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Rikka_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值