题目

区间 \(01\) 背包

\(1 \le l_i \le r_i \le n \le 20000,1 \le q \le 100000,1 \le m_i \le 500, 1 \le w_i \le 500, 1 \le v_i \le 10^6\)

分析

显然,我们考虑区间背包的合并

于是可以考虑分治策略

我们每次处理跨区间的询问

那么可以以 \(mid\) 为起点,往左做一遍后缀背包(不一定装满),往右做一遍前缀背包(一定装满)

一个在本区间且跨 \(mid\) 的询问就可以用这些拼起来,统计答案即可

不在本区间的分治处理即可

上面限制了背包装不装满是为了不重复的统计

于是时间复杂度就是 \(O(nm\log n + qm)\)

\(Code\)

#include<cstdio>
#include<vector>
#define ls (k << 1)
#define rs (ls | 1)
using namespace std; const int N = 2e4 + 5, M = 505, Q = 1e5 + 5;
const int INF = 0x3f3f3f3f, P = 998244353;
int n, q, Mx, v[N], w[N], f[N][M], g[N][M];
struct node{int l, r, m;}a[Q];
struct answer{int val, g;}ans[Q];
vector<int> st[Q << 2]; void solve(int k, int L, int R)
{
if (!st[k].size()) return;
int mid = (L + R) >> 1; f[mid][0] = 0, g[mid][0] = 1;
for(register int i = mid; i <= R; i++)
{
g[i][0] = 1;
for(register int j = 1; j <= Mx; j++) f[i][j] = -INF, g[i][j] = 0;
}
for(register int i = mid + 1; i <= R; i++)
{
for(register int j = 0; j <= Mx; j++) f[i][j] = f[i - 1][j], g[i][j] = g[i - 1][j];
for(register int j = w[i]; j <= Mx; j++)
{
int val = f[i - 1][j - w[i]] + v[i];
if (val > f[i][j]) f[i][j] = val, g[i][j] = g[i - 1][j - w[i]];
else if (val == f[i][j]) g[i][j] = (g[i][j] + g[i - 1][j - w[i]]) % P;
}
} for(register int i = mid; i >= L; i--)
for(register int j = 0; j <= Mx; j++) f[i][j] = 0, g[i][j] = 1;
for(register int i = w[mid]; i <= Mx; i++) f[mid][i] = v[mid], g[mid][i] = 1;
for(register int i = mid - 1; i >= L; i--)
{
for(register int j = 0; j <= Mx; j++) f[i][j] = f[i + 1][j], g[i][j] = g[i + 1][j];
for(register int j = w[i]; j <= Mx; j++)
{
int val = f[i + 1][j - w[i]] + v[i];
if (val > f[i][j]) f[i][j] = val, g[i][j] = g[i + 1][j - w[i]];
else if (val == f[i][j]) g[i][j] = (g[i][j] + g[i + 1][j - w[i]]) % P;
}
} for(register int i = 0; i < st[k].size(); i++)
{
int now = st[k][i], l = a[now].l, r = a[now].r, m = a[now].m;
if (l == mid && r == mid) ans[now].val = ((m >= w[mid]) ? (v[mid]) : 0), ans[now].g = 1;
else if (l > mid) st[rs].push_back(now);
else if (r <= mid) st[ls].push_back(now);
else{
for(register int j = 0; j <= m; j++)
{
int val = f[r][j] + f[l][m - j];
if (val > ans[now].val) ans[now].val = val, ans[now].g = (long long)g[r][j] * g[l][m - j] % P;
else if (val == ans[now].val) ans[now].g = (ans[now].g + (long long)g[r][j] * g[l][m - j]) % P;
}
}
} if (L == R) return;
solve(ls, L, mid), solve(rs, mid + 1, R);
} int main()
{
freopen("knapsack.in", "r", stdin);
freopen("knapsack.out", "w", stdout);
scanf("%d", &n);
for(register int i = 1; i <= n; i++) scanf("%d%d", &v[i], &w[i]);
scanf("%d", &q);
for(register int i = 1; i <= q; i++)
scanf("%d%d%d", &a[i].l, &a[i].r, &a[i].m), Mx = max(Mx, a[i].m), st[1].push_back(i);
solve(1, 1, n);
for(register int i = 1; i <= q; i++)
{
if (ans[i].val == 0) printf("0 0\n");
else printf("%d %d\n", ans[i].val, ans[i].g);
}
}

noip2020模拟赛 背包 (knapsack)的更多相关文章

  1. NOIP2020 模拟赛 B 组 Day6

    非常巧妙的一场模拟赛,比较偏向于 Atcoder 的风格,考场上做出了 A .C 两题. A. 礼物购买 排完序后一个个礼物地枚举时间复杂度是\(\Theta(nm)\)的,不能接受.但是注意到,若当 ...

  2. DP 01背包 七夕模拟赛

    问题 D: 七夕模拟赛 时间限制: 1 Sec  内存限制: 128 MB提交: 60  解决: 23[提交][状态][讨论版] 题目描述 " 找啊找啊找GF,找到一个好GF,吃顿饭啊拉拉手 ...

  3. 【noip模拟赛5】细菌 状压dp

    [noip模拟赛5]细菌   描述 近期,农场出现了D(1<=D<=15)种细菌.John要从他的 N(1<=N<=1,000)头奶牛中尽可能多地选些产奶.但是如果选中的奶牛携 ...

  4. NOIP模拟赛-2018.11.5

    NOIP模拟赛 好像最近每天都会有模拟赛了.今天从高二逃考试跑到高一机房,然而高一也要考试,这回好像没有拒绝的理由了. 今天的模拟赛好像很有技术含量的感觉. T1:xgy断句. 好诡异的题目,首先给出 ...

  5. ZROI提高组模拟赛05总结

    ZROI提高组模拟赛05总结 感觉是目前为止最简单的模拟赛了吧 但是依旧不尽人意... T1 有一半的人在30min前就A掉了 而我花了1h11min 就是一个简单的背包,我硬是转化了模型想了好久,生 ...

  6. 「NOIP模拟赛」数位和乘积(dp,高精)

    统计方案数,要么组合数,要么递推(dp)了. 这是有模拟赛历史以来爆炸最狠的一次 T1写了正解,也想到开long long,但是开错了地方然后数组开大了结果100->0 T3看错题本来简单模拟又 ...

  7. 「NOWCODER」CSP-S模拟赛第3场

    「NOWCODER」CSP模拟赛第3场 T1 货物收集 题目 考场思路即正解 T2 货物分组 题目 考场思路 题解 60pts 算法:一维 DP 100pts 算法:一维 DP ?线段树 + 单调栈 ...

  8. 20201101gryz模拟赛解题报告

    写在前面 2020rp++ 停课的第一场模拟赛 拿上一年的上一年的day1来考的, 结果得分期望220pts,实际135pts,rank3,太菜了 考着考着机房灯突然灭了,当时慌的一批 以为断电代码要 ...

  9. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  10. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

随机推荐

  1. 记一次windows10电脑连上wifi无法上网的解决问题

    前言 今天下午同学的电脑能连上wifi,但是却上不了互联网 开始思考 首先想到的肯定是WiFi驱动问题,但是wifi能连上大部分的原因可能就不是驱动问题了,为了彻底排除这个因素,我用到了我的usb网卡 ...

  2. 腾讯云数据库SaaS致力于构建数据库分布式云,为更多更广的用户提供服务

    大数据时代,数据库 SaaS 是企业实现降本增效和业务创新的重要抓手.在腾讯全球数字生态大会数据库 SaaS 专场上,腾讯云发布了多项数据库 SaaS 产品能力升级,并重点分享了其在上云.日常运维.数 ...

  3. Linux系统各种库/软件版本输出指令

    日常开发基于Linux系统(其实更多的是Ubuntu平台),平时总会遇到一些情况需要查看某个库或者软件的版本信息,在这里做一下简单的记录. 1. 查看glibc版本 方法一:使用ldd指令 cv@cv ...

  4. linux内核源码下载地址

    一.官网链接 https://www.kernel.org/ 二.HTTP https://www.kernel.org/pub/ 三.GIT https://git.kernel.org/ 四.镜像 ...

  5. 【软考-中级-数据库相关知识】03、SQL语言

    SQL语言 查询 允许出现聚集函数的是:select子句和having子句 权限管理 语法:GRANT XXX ON TABLE TO USER WITH GRANT OPTION 存储过程和函数 函 ...

  6. 【Java EE】Day12 XML、约束(DTD、Schema)、解析方式、Jsoup、选择器(Selector、XPath)

    一.XML介绍 1.概述 Extensible Markup Language--可扩展标记语言 标记语言 :标签构成 可扩展:可以自定义标签 2.功能 存储数据 作为配置文件使用 作为数据载体在网络 ...

  7. 【每日一题】【快速排序过程、循环过程无=、递归参数】2022年1月16日-NC140 排序

    快速排序 对时间复杂度和空间复杂度有要求 方法1:快速排序-递归 import java.util.*; public class Solution { /** * 代码中的类名.方法名.参数名已经指 ...

  8. React DevUI 18.0 正式发布🎉

    Jay 是一位经验丰富并且对质量要求很高的开发者,对 Angular.React 等多种框架都很熟悉,我们在开源社区认识,在我做开源社区运营的过程中,Jay 给了我很多帮助,他也是 React Dev ...

  9. 《HTTP权威指南》– 6.代理

    代理的概念: Web代理服务器是网络的中间实体.位于客户端和服务器之间,扮演"中间人"的角色,在各端点之间来回传送HTTP报文. 私有和共享代理: 代理服务器可以是某个客户端专用的 ...

  10. maven 项目依赖自动导入失败(pom.xml 文件爆红),解决--手动导入

    idea 报错信息提示:Dependency 'xxx' not found 解决方法:可以通过更换仓库的镜像配置解决,但是一般咱都在配置maven的时候,设置成阿里云仓库镜像了,更换成其他的,可能出 ...