洛谷 10月 csp-s 模拟赛 T1,T2解析及代码

T1 Magenta Potion

题目描述

给定一个长为 nnn 的整数序列 aaa,其中所有数的绝对值均大于等于 222。有 qqq 次操作,格式如下:

1 i k\text{1 i k}1 i k,表示将 aia_iai​ 修改为 kkk。保证 kkk 的绝对值大于等于 222。

2 l r\text{2 l r}2 l r,考虑 [l,r][l,r][l,r]的子区间(包括本身)中乘积最大的的区间乘积 MMM。如果 M>230M>2^{30}M>230,输出 Too large,否则输出 MMM。特别地,空区间的元素乘积定义为 111。

输入格式:
第一行两个正整数表示 n,qn,qn,q。

第二行输入 nnn 个整数表示 aia_iai​。

接下来 qqq 行,每行三个整数表示一次询问,格式见上。

输出格式:
对于每次 2\tt22 操作输出一行表示询问的答案。

数据范围:
对于所有的数据,2≤∣ai∣,∣k∣≤1092 \le |a_i|,|k| \le 10^{9}2≤∣ai​∣,∣k∣≤109,2≤n,q≤2×1052 \le n, q \le 2 \times 10^{5}2≤n,q≤2×105,1≤l,r≤n1 \le l, r \le n1≤l,r≤n。

解析

这道题乍一看是一道妥妥的线段树板子题,但是仔细观察 M>230M > 2^{30}M>230 和 ∣ai∣≥2|a_i| \ge 2∣ai​∣≥2 这两个条件可以得出一个结论:当 l−r+1≥62l - r + 1 \ge 62l−r+1≥62 时,MMM必定大于2302^{30}230。


证明
第一种情况,当lll到rrr这个区间上没有负数时,显然MMM就等于ala_lal​连乘到ara_rar​,这显然是≥262\ge 2^{62}≥262的。

第二种情况,当lll到rrr这个区间上有一个负数时,那么会有61个正数,而此时无论这个负数放在这个区间上的哪一个位置,必定会有一段正数的长度 ≥31\ge31≥31,而这一段正数的乘积也就显然≥231\ge 2^{31}≥231了。

第三种情况,当lll到rrr这个区间上有多于一个负数时,如果有偶数个,那么负负得正,就相当于没有负数,MMM就等于ala_lal​乘到ara_rar​;而如果有奇数个,事实上也就相当于只有一个负数了。


那么这道题就好做了,对于每一个询问 2\tt22,将所有 r−l+1≥62r - l + 1 \ge 62r−l+1≥62 的直接输出掉,剩下的直接暴力处理就行了。


暴力处理:
声明三个变量 cnt,first,lastcnt, first, lastcnt,first,last 分别表示 [l,r][l, r][l,r] 这个区间上负数的个数、第一个负数出现的位置和最后一个负数出现的位置。当 cntcntcnt 为偶数时,直接从 ala_lal​ 乘到 ara_rar​ 即可。当 cntcntcnt 为奇数时,答案只可能是这两种情况之一:

  1. afirst+1a_{first + 1}afirst+1​ 到 ara_rar​ 的所有数的乘积
  2. ala_lal​ 到 alast−1a_{last - 1}alast−1​ 的所有数的乘积

算一下就好了,注意在每次乘上一个数后都要判断是否有 ans>230ans>2^{30}ans>230,否则可能会爆long long影响判断。
时间复杂度 O(61×n)O(61 \times n)O(61×n) 。

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>using namespace std;typedef long long LL;const int N = 2e5 + 10, MAXINT = 1073741824;int n, q;
LL a[N];int main()
{scanf("%d%d", &n, &q);for(int i = 1 ; i <= n ; i ++ ) scanf("%lld", a + i);for(int i = 1 ; i <= q ; i ++ ){int type;scanf("%d", &type);if(type == 2){int l, r;scanf("%d%d", &l, &r);if(r - l + 1 >= 62){puts("Too large");continue;}int cnt = 0, first = -1, last = -1;for(int j = l ; j <= r ; j ++ ){if(a[j] < 0){last = j;if(!cnt) first = j;cnt ++ ;}}LL ans = 1;if(cnt % 2){bool flag = 0;for(int j = first + 1 ; j <= r ; j ++ ){ans *= a[j];if(abs(ans) > MAXINT){puts("Too large");flag = 1;break;}}if(ans < 0) flag = 1;if(!flag){LL t = ans;ans = 1;for(int j = last - 1 ; j >= l ; j -- ){ans *= a[j];if(abs(ans) > MAXINT){puts("Too large");flag = 1;break;}}if(ans < 0) flag = 1;if(!flag) ans = max(ans, t), printf("%lld\n", ans);}}else{bool flag = 0;LL ans = 1;for(int j = l ; j <= r ; j ++ ){ans *= a[j];if(abs(ans) > MAXINT){puts("Too large");flag = 1;break;}}if(ans < 0) flag = 1;if(!flag) printf("%lld\n", ans);}}else{int i;LL k;scanf("%d%lld", &i, &k);a[i] = k;}}
}

T2 ρars/ey

题目描述

给定一颗有 nnn 个节点的有根树,其中根节点是 111。你可以进行若干次以下操作:
选择一个节点,删去其子树内除其以外的点。
此操作的代价为 fif_ifi​,其中 iii 是你选择的节点子树大小。
你希望删掉除了 111 以外的所有点,请问代价的最小值是多少?

输入格式:
第一行一个正整数 nnn 。
第二行 n−1n-1n−1 个正整数,第 iii 个表示 fi+1f_{i+1}fi+1​ 。
接下来 n−1n-1n−1 行,每行两个正整数,表示一条树边。

输出格式:
一行一个正整数表示答案。

数据范围:
对于所有数据,保证 1≤n≤50001 \le n \le 50001≤n≤5000,1≤fi≤1091 \le f_i \le 10^{9}1≤fi​≤109。

解析

基本可以确定是一道dp题。
先设状态:
f[i][j]f[i][j]f[i][j] 表示以 iii 为根节点的子树中删除了 jjj 个点时的最小花费。

那么就可以得到状态转移方程:
f[i][j]=min⁡v∈son(i)(f[i][j−k]+f[v][k])f[i][j] = \min\limits_{v\in son(i)}(f[i][j - k] + f[v][k])f[i][j]=v∈son(i)min​(f[i][j−k]+f[v][k])
该方程的含义为 f[i][j]f[i][j]f[i][j] 从 iii 的所有儿子节点转移得到,枚举儿子节点 vvv 以及从以 vvv 为根的子树中删除的点的数量 kkk 来转移到 f[i][j]f[i][j]f[i][j] 。
但是注意到这个方程由于默认了保留所有儿子节点,所以方程中的 jjj 最大只能到 sizei−1−cntsonisize_{i} - 1 - cntson_{i}sizei​−1−cntsoni​ ,其中 cntsonicntson_{i}cntsoni​ 表示 iii 的儿子节点的数量。
所以我们还需要一个转移方程来得到答案:
f[i][sizei−1]=min⁡j=0sizei−1(f[i][j]+w[sizei−j])f[i][size_{i} - 1] = \min\limits_{j = 0}^{size_{i} - 1}(f[i][j] + w[size_{i} - j])f[i][sizei​−1]=j=0minsizei​−1​(f[i][j]+w[sizei​−j])
时间复杂度 O(n2)O(n^{2})O(n2) 。

代码

#include <iostream>
#include <algorithm>
#include <cstring>#define INF 0x7f7f7f7f7f7f7f7fusing namespace std;typedef long long LL;const int N = 5010;int n;
int w[N];
int h[N], idx;
LL f[N][N], sz[N];struct Edge
{int ne, e;
}edges[N + N];void add(int a, int b)
{edges[ ++ idx].e = b, edges[idx].ne = h[a], h[a] = idx;
}void dfs(int u, int last)
{f[u][0] = 0;sz[u] = 1;for(int i = h[u] ; i ; i = edges[i].ne){int v = edges[i].e;if(v == last) continue;dfs(v, u);for(int j = sz[u] + sz[v] - 1 ; j > 0 ; j -- )for(int k = max(j - sz[u], 1ll) ; k <= sz[v] - 1 && k <= j ; k ++ ){if(f[v][k] >= INF || f[u][j - k] >= INF) continue;f[u][j] = min(f[u][j], f[u][j - k] + f[v][k]);}sz[u] += sz[v];}for(int i = 0 ; i <= sz[u] - 1 ; i ++ )f[u][sz[u] - 1] = min(f[u][sz[u] - 1], f[u][i] + 1ll * w[sz[u] - i]);
}int main()
{
//  freopen("T2in.txt", "r", stdin);scanf("%d", &n);for(int i = 2 ; i <= n ; i ++ ) scanf("%d", w + i);for(int i = 1 ; i < n ; i ++ ){int u, v;scanf("%d%d", &u, &v);add(u, v), add(v, u);}memset(f, 0x7f, sizeof f);dfs(1, 0);printf("%lld\n", f[1][sz[1] - 1]);return 0;
}

洛谷 10月 csp-s 模拟赛 T1,T2解析及代码相关推荐

  1. 洛谷 P5594 【XR-4】模拟赛 视频讲解(二维数组、模拟)

    洛谷 P5594 [XR-4]模拟赛(需要 二维数组) 题目描述 X 校正在进行 CSP 前的校内集训. 一共有 nn 名 OIer 参与这次集训,教练为他们精心准备了 mm 套模拟赛题. 然而,每名 ...

  2. 2021年10月8日模拟赛(保龄奇遇记)

    本场考试考的很撇,值得反思,暴露出很多问题,望及时的拨乱反正,改掉操之过急,心态不稳定的缺点 2021年10月8日模拟赛(保龄奇遇记) 太菜了 T1 话中有话 有些词是多义词.这就导致同一句话可能有多 ...

  3. 洛谷10月月赛 2 t2 深海少女与胖头鱼

    洛谷10月月赛 2 t2 深海少女与胖头鱼 题目链接 参考资料:洛谷10月赛2讲评ppt; 本篇题解考完那天就开始写,断断续续写到今天才写完 本题作为基础的期望dp题,用来学习期望dp还是很不错的 ( ...

  4. 洛谷:P5594 【XR-4】模拟赛

    [XR-4]模拟赛 题目描述 X 校正在进行 CSP 前的校内集训. 一共有 nnn 名 OIer 参与这次集训,教练为他们精心准备了 mmm 套模拟赛题. 然而,每名 OIer 都有各自的时间安排, ...

  5. 洛谷 P5594 【XR-4】模拟赛 记录

    洛谷 P5594 笔记 本人菜鸡,入门刷题记录,有错望指出 1.matrix过大时放在main函数里会爆栈,运行不了,改成全局变量 2.第一次做的时候,先整个矩阵读取,再对每天都遍历整个二维数组,时间 ...

  6. 【洛谷】NOIP提高组模拟赛Day2【动态开节点/树状数组】【双头链表模拟】

    U41571 Agent2 题目背景 炎炎夏日还没有过去,Agent们没有一个想出去外面搞事情的.每当ENLIGHTENED总部组织活动时,人人都说有空,结果到了活动日,却一个接着一个咕咕咕了.只有不 ...

  7. 洛谷10月月赛Round.1| P3399 丝绸之路 [DP]

    题目背景 张骞于公元前138年曾历尽艰险出使过西域.加强了汉朝与西域各国的友好往来.从那以后,一队队骆驼商队在这漫长的商贸大道上行进,他们越过崇山峻岭,将中国的先进技术带向中亚.西亚和欧洲,将那里的香 ...

  8. 洛谷10月月赛II题解

    Solution T1 首先,可以一眼看出这是一个完全图的一笔画问题.然后开始挖性质: ①根据欧拉图的性质,如果将我们一笔画中没有经过的边删去,那么剩下的节点的度数一定有000个或222个是奇数. 通 ...

  9. 洛谷10月月赛Round.1| P3400 仓鼠窝[单调栈]

    题目描述 萌萌哒的Created equal是一只小仓鼠,小仓鼠自然有仓鼠窝啦. 仓鼠窝是一个由n*m个格子组成的行数为n.列数为m的矩阵.小仓鼠现在想要知道,这个矩阵中有多少个子矩阵!(实际上就是有 ...

最新文章

  1. [转]Effective C# 原则5:始终提供ToString()
  2. 华为「硬」生生把AI搞出暴力美学
  3. python 文件操作 os.mkdir()函数
  4. Mybatis insert操作细节【ID】
  5. java js highcharts_Highcharts.js -纯javasctipt图表库初体验
  6. Pandas一些小技巧
  7. 比亚迪汉鸿蒙系统测评_深度:预判比亚迪汉EV电驱动系统技术状态
  8. HDF5 library version mismatched error
  9. 产品密钥无法激活成功,最后使用visio2013激活软件激活成功。
  10. Mac下nginx的安装记录(亲测可用)
  11. fastboot刷机工具_红魔3/3S 刷机教程
  12. 西餐菜单怎么翻译成英文
  13. SHA-512摘要算法(带示例)
  14. html 通知页面,消息通知页面.html
  15. 修改远程计算机 时间,Pubwin服务器时间修改的四种办法
  16. php搞笑证件,什么软件可以制作搞笑证件,多种搞笑证件制作
  17. 关于weight_decay的设定
  18. 谷歌二次验证器手机里不能使用怎么办?
  19. 20162316刘诚昊 课程总结
  20. AIX中常用的SMIT 的使用

热门文章

  1. Scrapy笔记-保存到数据库
  2. CSDN看书的书架入口
  3. 基于MATLAB编写的GNSS_SDR(GNSS软件接收机)——自学笔记(3)
  4. 平台程序微信平台开发应用的签名
  5. DBLP数据集XML使用python SAX解析 作者名字显示错误问题
  6. CVPR2022: Oriented RepPoints论文模型实践(用dota数据集)
  7. 教大家如何用一行代码打造下载神器!下载全网视频、音频、图像!太牛了!
  8. 文化部查处第九批违法游戏及经营活动的通知
  9. python 爬虫-(2)认识爬虫
  10. win10怎么连接android手机,如何将手机与Win10电脑关联以在电脑上继续任务?