mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-08-21 18:52:07 +00:00
update
This commit is contained in:
parent
3477697f90
commit
c24b145946
@ -1,38 +1,151 @@
|
|||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <istream>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
using ll = int64_t;
|
typedef long long ll; // 定义长整型别名,用于处理大数
|
||||||
static inline constexpr std::string cvtfd(ll n,ll b){
|
|
||||||
std::string s;
|
int main() {
|
||||||
do{
|
ios::sync_with_stdio(false);
|
||||||
ll c=n%b;
|
cin.tie(0); // 优化输入输出速度
|
||||||
s=char(c+'0')+s;
|
|
||||||
n/=b;
|
int k;
|
||||||
}while(n);
|
cin >> k; // 读取数字集合大小
|
||||||
return s;
|
vector<int> d(k); // 存储数字集合
|
||||||
}
|
for (int i = 0; i < k; i++) {
|
||||||
ll k,q;
|
cin >> d[i]; // 读取数字集合元素
|
||||||
std::vector<char> d;
|
}
|
||||||
int main(){
|
|
||||||
std::iostream::sync_with_stdio(false);
|
// 检查数字集合是否包含0
|
||||||
std::cin>>k;
|
bool has_zero = (d[0] == 0);
|
||||||
d.resize(k);
|
// 计算首位可用数字数量(首位不能为0)
|
||||||
for(char&c:d){
|
int m = has_zero ? k - 1 : k;
|
||||||
ll tmp;
|
|
||||||
std::cin>>tmp;
|
// 创建首位可用数字数组
|
||||||
c=tmp+'0';
|
vector<int> arr;
|
||||||
}
|
if (has_zero) {
|
||||||
std::cin>>q;
|
// 如果含0,首位使用除0外的其他数字
|
||||||
while(q--){
|
arr = vector<int>(d.begin() + 1, d.end());
|
||||||
ll n;
|
} else {
|
||||||
std::cin>>n;
|
// 如果不含0,所有数字都可用于首位
|
||||||
std::string s = cvtfd(n,d.size());
|
arr = d;
|
||||||
for(char c:s){
|
}
|
||||||
std::cout<<d[c-'0'];
|
|
||||||
}
|
// 存储各长度幸运数的数量
|
||||||
std::cout<<'\n';
|
vector<ll> cnt;
|
||||||
}
|
// 存储幸运数数量的前缀和
|
||||||
|
vector<ll> prefix;
|
||||||
|
ll total = 0; // 累计幸运数总数
|
||||||
|
int max_len = 0; // 最大长度
|
||||||
|
|
||||||
|
// 计算各长度幸运数的数量
|
||||||
|
for (int len = 1; ; len++) {
|
||||||
|
ll count_this; // 当前长度的幸运数数量
|
||||||
|
|
||||||
|
if (len == 1) {
|
||||||
|
// 长度为1:只有首位数字
|
||||||
|
count_this = m;
|
||||||
|
} else {
|
||||||
|
count_this = m; // 首位有m种选择
|
||||||
|
// 计算剩余len-1位的组合数
|
||||||
|
for (int i = 1; i < len; i++) {
|
||||||
|
// 防止溢出,超过10^18时设为极大值
|
||||||
|
if (count_this > 1000000000000000000LL / k) {
|
||||||
|
count_this = 1000000000000000001LL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
count_this = count_this * k; // 每增加一位,数量乘以k
|
||||||
|
}
|
||||||
|
// 再次检查溢出
|
||||||
|
if (count_this > 1000000000000000000LL) {
|
||||||
|
count_this = 1000000000000000001LL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新总数
|
||||||
|
total += count_this;
|
||||||
|
// 防止总数溢出
|
||||||
|
if (total > 1000000000000000000LL) {
|
||||||
|
total = 1000000000000000001LL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存储当前长度数量和前缀和
|
||||||
|
cnt.push_back(count_this);
|
||||||
|
prefix.push_back(total);
|
||||||
|
max_len++; // 增加长度计数
|
||||||
|
|
||||||
|
// 当总数超过10^18时停止计算
|
||||||
|
if (total >= 1000000000000000000LL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int q;
|
||||||
|
cin >> q; // 读取查询数量
|
||||||
|
while (q--) {
|
||||||
|
ll x;
|
||||||
|
cin >> x; // 读取查询的序号
|
||||||
|
|
||||||
|
ll prev = 0; // 存储当前长度之前的所有幸运数数量
|
||||||
|
int cur_len = -1; // 存储目标幸运数的长度
|
||||||
|
|
||||||
|
// 查找目标幸运数所在长度区间
|
||||||
|
for (int i = 0; i < max_len; i++) {
|
||||||
|
if (x <= prefix[i]) {
|
||||||
|
cur_len = i + 1; // 确定长度
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prev = prefix[i]; // 更新前缀和
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理极端情况(理论上不会发生)
|
||||||
|
if (cur_len == -1) {
|
||||||
|
cur_len = max_len;
|
||||||
|
prev = prefix.back() - cnt.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算在当前长度组内的位置
|
||||||
|
ll pos = x - prev;
|
||||||
|
int r = cur_len - 1; // 剩余位数(除首位外)
|
||||||
|
|
||||||
|
// 计算剩余位数的基数(k^(r))
|
||||||
|
ll base_val = 1;
|
||||||
|
if (r > 0) {
|
||||||
|
for (int i = 0; i < r; i++) {
|
||||||
|
// 防止溢出
|
||||||
|
if (base_val > 1000000000000000000LL / k) {
|
||||||
|
base_val = 1000000000000000001LL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
base_val = base_val * k;
|
||||||
|
}
|
||||||
|
// 再次检查溢出
|
||||||
|
if (base_val > 1000000000000000000LL) {
|
||||||
|
base_val = 1000000000000000001LL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算首位在arr中的索引
|
||||||
|
ll idx0 = (pos - 1) / base_val;
|
||||||
|
cout << arr[idx0]; // 输出首位数字
|
||||||
|
|
||||||
|
// 处理剩余位数
|
||||||
|
if (r > 0) {
|
||||||
|
ll rem = (pos - 1) % base_val; // 剩余部分的位置
|
||||||
|
vector<int> digits(r, 0); // 存储各位数字索引
|
||||||
|
|
||||||
|
// 将rem转换为k进制表示
|
||||||
|
for (int i = 0; i < r; i++) {
|
||||||
|
digits[r - 1 - i] = rem % k; // 从低位到高位存储
|
||||||
|
rem /= k;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 输出剩余位数的数字
|
||||||
|
for (int i = 0; i < r; i++) {
|
||||||
|
cout << d[digits[i]]; // 输出对应数字
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << '\n'; // 换行
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
93
src/8/2/T644760.cpp
Normal file
93
src/8/2/T644760.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <cstring>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// 解决单次查询的函数,计算区间[l, r]内满足条件的(n, m)对数量
|
||||||
|
long long solve(long long l, long long r) {
|
||||||
|
if (l > r) return 0; // 无效区间直接返回0
|
||||||
|
|
||||||
|
// 预处理l和r的31位二进制表示(从最高位到最低位)
|
||||||
|
int bits_r[31], bits_l[31]; // 存储二进制位
|
||||||
|
for (int i = 0; i < 31; i++) {
|
||||||
|
// 提取r的第(30-i)位(最高位存储在bits_r[0])
|
||||||
|
bits_r[i] = (r >> (30 - i)) & 1;
|
||||||
|
// 提取l的第(30-i)位(最高位存储在bits_l[0])
|
||||||
|
bits_l[i] = (l >> (30 - i)) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DP数组:dp[i][tight_n][tight_l]
|
||||||
|
// i: 当前处理的位数(0-30)
|
||||||
|
// tight_n: n是否仍受r的上界约束(1-受约束,0-不受约束)
|
||||||
|
// tight_l: m是否仍受l的下界约束(1-受约束,0-不受约束)
|
||||||
|
long long dp[32][2][2];
|
||||||
|
memset(dp, 0, sizeof(dp)); // 初始化DP数组为0
|
||||||
|
dp[0][1][1] = 1; // 初始状态:从最高位开始,n和m都受约束
|
||||||
|
|
||||||
|
// 从高位到低位遍历31个二进制位
|
||||||
|
for (int i = 0; i < 31; i++) {
|
||||||
|
// 遍历所有可能的约束状态
|
||||||
|
for (int tight_n = 0; tight_n < 2; tight_n++) {
|
||||||
|
for (int tight_l = 0; tight_l < 2; tight_l++) {
|
||||||
|
if (dp[i][tight_n][tight_l] == 0) continue; // 跳过无效状态
|
||||||
|
|
||||||
|
// 确定n当前位的上限:
|
||||||
|
// 若受约束则上限为r的当前位,否则上限为1
|
||||||
|
int up_n = (tight_n) ? bits_r[i] : 1;
|
||||||
|
|
||||||
|
// 枚举n当前位的可能取值a(0或1)
|
||||||
|
for (int a = 0; a <= up_n; a++) {
|
||||||
|
// 根据m是否受下界约束分情况处理
|
||||||
|
if (tight_l) {
|
||||||
|
// 若受约束,则m当前位b的下限为l的当前位
|
||||||
|
int low_m = bits_l[i];
|
||||||
|
// 枚举m当前位b的可能取值(从low_m到1)
|
||||||
|
for (int b = low_m; b <= 1; b++) {
|
||||||
|
// 检查子集条件:m的位不能超过n
|
||||||
|
if (b == 1 && a == 0) continue; // 违反条件则跳过
|
||||||
|
|
||||||
|
// 计算新的约束状态:
|
||||||
|
// 若之前受约束且当前位等于边界值,则继续保持约束
|
||||||
|
int new_tight_n = tight_n && (a == bits_r[i]);
|
||||||
|
int new_tight_l = tight_l && (b == bits_l[i]);
|
||||||
|
|
||||||
|
// 状态转移:累加方案数
|
||||||
|
dp[i+1][new_tight_n][new_tight_l] += dp[i][tight_n][tight_l];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 若不受约束,则b可取0或1
|
||||||
|
for (int b = 0; b <= 1; b++) {
|
||||||
|
// 检查子集条件
|
||||||
|
if (b == 1 && a == 0) continue;
|
||||||
|
|
||||||
|
// 计算新的约束状态(下界约束保持解除状态)
|
||||||
|
int new_tight_n = tight_n && (a == bits_r[i]);
|
||||||
|
int new_tight_l = tight_l; // 下界约束一旦解除不再恢复
|
||||||
|
dp[i+1][new_tight_n][new_tight_l] += dp[i][tight_n][tight_l];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统计所有最终状态的结果
|
||||||
|
long long ans = 0;
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
for (int j = 0; j < 2; j++)
|
||||||
|
ans += dp[31][i][j];
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
ios::sync_with_stdio(false);
|
||||||
|
cin.tie(0); // 优化输入输出
|
||||||
|
|
||||||
|
int q;
|
||||||
|
cin >> q; // 读取查询次数
|
||||||
|
while (q--) {
|
||||||
|
long long l, r;
|
||||||
|
cin >> l >> r; // 读取查询区间
|
||||||
|
cout << solve(l, r) << '\n'; // 输出答案
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
52
src/8/2/T644761.cpp
Normal file
52
src/8/2/T644761.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <istream>
|
||||||
|
#include <vector>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
typedef long long ll;
|
||||||
|
const int MOD = 998244353;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
iostream::sync_with_stdio(false);
|
||||||
|
cin.tie(nullptr);
|
||||||
|
ll n, a, b, c;
|
||||||
|
cin >> n >> a >> b >> c;
|
||||||
|
|
||||||
|
|
||||||
|
vector<vector<ll>> C(n+1, vector<ll>(n+1, 0));
|
||||||
|
for (int i = 0; i <= n; i++) {
|
||||||
|
C[i][0] = 1;
|
||||||
|
for (int j = 1; j <= i; j++) {
|
||||||
|
C[i][j] = (C[i-1][j-1] + C[i-1][j]) % MOD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
auto S = [&](ll m, ll x) -> ll {
|
||||||
|
if (m < 0) return 0;
|
||||||
|
ll up = min(m, x);
|
||||||
|
ll sum = 0;
|
||||||
|
for (int i = 0; i <= up; i++) {
|
||||||
|
sum = (sum + C[m][i]) % MOD;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ll ans = 0;
|
||||||
|
for (int k = 0; k <= n; k++) {
|
||||||
|
ll m = n - k;
|
||||||
|
ll t = C[n][k];
|
||||||
|
t = t * S(m, a) % MOD;
|
||||||
|
t = t * S(m, b) % MOD;
|
||||||
|
t = t * S(m, c) % MOD;
|
||||||
|
|
||||||
|
if (k % 2 == 1) {
|
||||||
|
t = MOD - t;
|
||||||
|
}
|
||||||
|
ans = (ans + t) % MOD;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << (ans % MOD + MOD) % MOD << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user