当前位置: 首页 > news >正文

2025ICPC武汉邀请赛-F

题意如下图

思路:
考虑一种贪心策略,

假设最大的物品体积为2^v,那么我每个背包都至少要有2^v的体积,那么假设有m个背包,我的容量就增加了m*2^v,如果此时最大的物品有k个,那么现在可以支配给后面小物品的体积就就有(m-k)*2^v也就是(m-k)个2^v,但是这个可支配体积难以表示,所以可以逐位考虑,如果在2^v对应的这个位置有a个可以支配给后面物品的体积,那么在2^(v-1)对应的位置就有2*a个可以支配给后面物品的体积,这样逐位计算,可以做到不用计算体积也能把体积分配下去

用一个简单的图示可以表示这种做法

如图1:2^i下面的1的个数对应物品这一位对应物品个数(这个样例k也就是背包数量为4)

此时只能把背包容量从0扩到2^4

图2,'-'表示背包扩容之后可以支配的体积,用了3个,还剩一个可支配的体积,乘2给到下一位

 图三,刚好抵掉2^3这一位

图四:背包容量从2^4扩容到2^4+2^2,多四个2^2的可支配的体积,用了三个剩一个

 图五:乘二

图六:乘二刚好抵掉,所以这个样例答案为2^4+2^2=20

按照这个思路,可以初步实现代码,但是还有一种情况就是2^m级别的体积向下转移到2^(m-1e9),也就是如果可以支配的有剩余,就会不断*2转移到下一位,但是根据数据范围可以发现可能会出现转移1e9次的情况,这种情况可以发现,转移32次以上,可支配的体积已经达到了2*32级别,那么可支配的体积一定容得下剩余的体积,于是提前结束循环得出答案即可

但是要注意,初始的某一位的物品个数如果超过了背包个数k,那么多余部分要除以二向高位转移,确保每一位的物品个数<=k

代码实现:

#include <map>
#include <set>
#include <queue>
#include <deque>
#include <cmath>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define fi first
#define se second
#define u1 (u<<1)
#define u2 (u<<1|1)
#define pb push_back
#define pp pop_back()
#define int long long
#define laile cout<<"laile"<<endl
#define lowbit(x) ((x)&(-x))
#define double long double
#define sf(x) scanf("%lld",&x)
#define sff(x,y) scanf("%lld %lld",&x,&y)
#define sd(x) scanf("%Lf",&x)
#define sdd(x,y) scanf("%Lf %Lf",&x,&y)
#define _for(i,n) for(int i=0;i<(n);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
#define _pre(i,a,b) for(int i=(a);i>=(b);--i)
#define all(x) (x).begin(), (x).end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef unsigned long long ULL;
typedef pair<int,int>PII;
const int N=6e6+10,INF=4e18,P=998244353;
int n,m;
int qmi(int a,int b,int P){int res=1;while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}return res;
}
vector<PII>v(N);
void solve()
{map<int,int>mp;cin>>n>>m;_rep(i,1,n){int a,b;cin>>a>>b;mp[b]+=a;}int idx=0;for(auto i:mp){if(i.se>m){int sub=i.se-m;mp[i.fi]-=sub;if(sub&1){sub++;mp[i.fi]--;}mp[i.fi+1]+=sub/2;}if(mp[i.fi]){v[++idx]={i.fi,mp[i.fi]};}}int pre=-1,res=0,fu=0;_pre(i,idx,1){if(pre==-1){res+=qmi(2,v[i].fi,P);fu=m-v[i].se;}else{if(fu&&pre-v[i].fi>40){cout<<res<<'\n';return ;}else{if(fu){for(int j=pre;j>v[i].fi;j--){//2^jfu*=2;if(fu>2*m){cout<<res<<'\n';return ;}}}if(fu>=v[i].se)fu-=v[i].se;else {v[i].se-=fu;//剩res=res+qmi(2,v[i].fi,P);res%=P;fu=m-v[i].se;}}}pre=v[i].fi;}cout<<res<<'\n';return ;
}
signed main()
{IOS;int T=1;cin>>T;while(T--)solve();return 0;
}

相关文章:

  • 【c# 类型转换中 as 和()】
  • DAY29 超大力王爱学Python
  • Java异常处理与File类终极指南
  • Java高频面试之并发编程-19
  • 【Qt】在OrinNX上,使用命令安装qtmultimedia5-dev时报错
  • VMware三种网络配置对比
  • 【华为OD- B卷 - 增强的strstr 100分(python、java、c++、js、c)】
  • 如何解决全局或静态变量被修改的bug
  • 高频Java面试题深度拆解:String/StringBuilder/StringBuffer三剑客对决(万字长文预警)
  • SpringBoot 自动配置
  • FEKO许可证与其他电磁仿真软件的比较
  • 2024年热门AI趋势及回顾
  • leetcode 3355. 零数组变换 I 中等
  • PYTHON训练营DAY31
  • ⼆叉搜索树详解
  • 迅为RK3562开发板旋转Uboot logo和内核logo
  • string在c语言中代表什么(非常详细)
  • VitePress 中以中文字符结尾的字体加粗 Markdown 格式无法解析
  • 嵌入式学习笔记 D24 :系统编程之i/o操作
  • PyTorch 之 torch.distributions.Categorical 详解
  • 第九届非遗节首设主宾国主宾城机制,非遗品牌IP授权获关注
  • 哪都“差一点”的《歌手2025》,还能爆吗?
  • 海南省市监局与香港标准及检定中心签署合作协议,加快检验检测国际化
  • 陕西籍青年作家卜文哲爬山时发生意外离世,终年28岁
  • 金爵奖主竞赛单元评委名单公布,中国评委有黄渤、咏梅等人
  • 中纪报:强化监督推动过紧日子要求落到实处