[题解] AT_ABC406_E Popcount Sum 3
题目大意
给你正整数 \(N\) 和 \(K\)。
求所有不超过 \(N\) 且满足以下条件的正整数 \(x\) 的 和(取模 \(998244353\)):
- \(x\) 的 \(\mathrm{popcount}\) 恰好是 \(K\) 。
给你 \(T\) 个测试用例,请逐个求解。
什么是 \(\mathrm{popcount}\)?
对于正整数 \(y\),\(\mathrm{popcount}(y)\) 表示 \(y\) 的二进制表示中 \(1\) 位的数目。
例如,\(\mathrm{popcount}(5)=2\),\(\mathrm{popcount}(16)=1\),\(\mathrm{popcount}(25)=3\)。
思路
因为题目让我们在一个范围 \(1\sim N\) 中符合条件的数的和,\(N\) 的上界是 \(2^{60}\),是个二进制数,可以拆位。
所以,我们考虑使用数位dp来做。
状态定义
设 \(f_{i,j}\) 表示从高望低数前 \(i\) 位二进制,恰好有 \(j\) 个 \(1\) 的个数。
\(s_{i,j}\) 表示这些数的和。
状态转移:
\(f_{i,j}=f_{i+1,j}+f_{i+1,j+1}\)
\(s_{i,j}=s_{i+1,j}+s_{i+1,j+1}+2^i\times f_{i+1,j+1}\)
解释
\(s_{i+1,j}\) 和 \(s_{i+1,j+1}\) 表示第 \(i\) 位为 \(0/1\) 的数字和。
\(2^i\times s_{i+1,j+1}\) 表示第 \(i\) 位为 \(1\) 的贡献(第 \(i\) 位数 \(\times\) 方案数)。
做法
- 用记忆化搜索进行数位dp。
- 用
pair<int,int>代表 \(f\) 和 \(s\) 数组。
代码
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 105;
const int mod = 998244353;
vector<int> bits;
int n, k;
pair<int,int> dp[N][N][2];
int qpow(int a, int b) {
a %= mod;
int ans = 1;
while (b) {
if (b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans % mod;
}
pair<int, int> dfs(int pos, int cnt, int tag){
//当前处理到pos为,有cnt个1,高位是否存在限制
if(pos == bits.size()){
if(cnt == k) return {1, 0};
else return {0, 1};
}
if(dp[pos][cnt][tag].first != -1){
return dp[pos][cnt][tag];
}
int rcnt = 0, rsum = 0;
int mx = tag? bits[pos] : 1;
for(int d = 0; d <= mx; d++){
if(cnt + d > k) continue;
auto [ncnt, nsum] = dfs(pos + 1, cnt + d, tag & (d == bits[pos]));
if(ncnt == 0) continue;
rcnt += ncnt;
int len = bits.size();
rsum += d * qpow(2, len-1-pos) % mod * ncnt % mod + nsum;
rcnt %= mod;
rsum %= mod;
}
dp[pos][cnt][tag] = {rcnt, rsum};
return dp[pos][cnt][tag];
}
inline void init(){
memset(dp, -1, sizeof(dp));
bits.clear();
return ;
}
void solve(){
init();
cin >> n >> k;
int m = n;
while(m > 0){
bits.push_back(m % 2);
m /= 2;
}
reverse(bits.begin(), bits.end());
if(k > bits.size()) {
cout << 0 << endl;
return ;
}
return cout << dfs(0, 0, 1).second << endl,void();
}
inline int read(){int x;cin>>x;return x;}
signed main(){
cin.tie(0)->sync_with_stdio(0);
int _=read();
while(_--) solve();
return 0;
}
[题解] AT_ABC406_E Popcount Sum 3的更多相关文章
- [LeetCode 题解]:Path Sum
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given a bi ...
- LeetCode题解39.Combination Sum
39. Combination Sum Given a set of candidate numbers (C) (without duplicates) and a target number (T ...
- PAT甲题题解-1081. Rational Sum (20)-模拟分数计算
模拟计算一些分数的和,结果以带分数的形式输出注意一些细节即可 #include <iostream> #include <cstdio> #include <algori ...
- 《LeetBook》LeetCode题解(1) : Two Sum[E]——哈希Map的应用
001.Two Sum[E] Two SumE 题目 思路 1双重循环 2 排序 3 Hashmap 1.题目 Given an array of integers, return indices o ...
- [题解] CF622F The Sum of the k-th Powers
CF622F The Sum of the k-th Powers 题意:给\(n\)和\(k\),让你求\(\sum\limits_{i = 1} ^ n i^k \ mod \ 10^9 + 7\ ...
- 题解 CF920F 【SUM and REPLACE】
可以事先打表观察每个数的约数个数,观察到如果进行替换,若干次后这个数便会被替换成1. 所以我们可以直接暴力的进行区间修改,若这个数已经到达1或2,则以后就不再修改,用并查集和树状数组进行维护. 这个方 ...
- LeetCode 题解之 Two Sum
1.题目描述 2.问题分析 使用hashTable 寻找,target - num[i] ,将时间复杂度降低到 O(n): 3.代码 vector<int> twoSum(vector ...
- LeetCode题解之 two sum 问题
1.题目描述 2.题目分析 考虑使用hashMap的方式将数组中的每个元素和下表对应存储起来,然后遍历数组,计算target 和 数组中每个元素的差值,在hashMap中寻找,一直到找到最后一对. 3 ...
- leetcode个人题解——#39 Combination Sum
思路:先对数据进行排序(看评论给的测试数据好像都是有序数组了,但题目里没有给出这个条件),然后回溯加剪枝即可. class Solution { public: ; vector<vector& ...
- LeetCode题解 #1 Two Sum
在LeetCode做的第一到题 题目大意:给出n个数,在其中找出和为一个特定数的两个数. Input: numbers={2, 7, 11, 15}, target=9Output: index1=1 ...
随机推荐
- 47.3K star!这款开源RAG引擎真香!文档理解+精准检索+可视化干预,一站式搞定!
嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 RAGFlow 是基于深度文档理解的开源RAG引擎,通过与LLM结合提供带精准引用的问答能力 ...
- mybatis—— 一个空格引发的血案
环境描述: 我在使用SSM做项目的时候需要一个需求:一个用户有多个角色,一个角色有多个权限,我需要根据用户的id找到用户的所有角色,及其对应的权限. 数据库是这个样子,users_role表记录了用户 ...
- windows查看连接过wifi的密码
如何使用批处理脚本获取已保存的WiFi密码 在日常使用电脑时,我们经常会连接多个WiFi网络.随着时间的推移,可能会忘记某些WiFi的密码.幸运的是,Windows系统提供了命令行工具netsh,可以 ...
- 漏洞预警 | WordPress Plugin Radio Player SSRF漏洞
0x00 漏洞编号 CVE-2024-54385 0x01 危险等级 高危 0x02 漏洞概述 WordPress插件Radio Player是一种简单而有效的解决方案,用于将实时流媒体音频添加到您的 ...
- Allure2+Maven+Testng部署及使用详细教程
AllureReport部署 前言:最近做自动化测试要用到AllureReport生成测试报告,网上逛了一下,发现有很多帖子,但是大家描述的都模棱两可,没有详细的步骤,因此编写此贴对部署方式进行记录; ...
- codeup之字符串比较
Description 比较两个字符串s1和s2的大小,如果s1>s2,则输出一个正数:若s1=s2,则输出0:若s1<s2,则输出一个负数. 要求:不用strcpy函数:两个字符串用ge ...
- ElementPlus插件的安装和使用
ElementPlus插件安装和使用 npm install element-plus --save src/main.ts新增 // 关键节点:全局注册 Element Plus,包含样式 impo ...
- Web安全入门学习--攻防世界web安全新手区过关心得
这几天也是废了小小功夫,完成了这十道题目. 这十道题目说难不难,说简单对刚入门的同学来说也没有那么简单,但是做完可以对web有最初步的了解 下面开始解题 1.view_source 作为第一题,这题还 ...
- WindowsPE文件格式入门01.PE头
https://www.bpsend.net/thread-288-1-2.html portable excute 可移植,可执行的文件(exe dll) 能够解析的文件,其内部都是有格式的,不是 ...
- cookie,session以及application的比较
cookie工作原理: cookie代码: 1 @WebServlet(value = "/cookie",name = "CookieServlet") 2 ...