《深入浅出进阶篇》——空间换时间优化——P2671 求和

news/2024/7/7 19:58:24

链接:https://www.luogu.com.cn/problem/P2671

上题干:

题目描述

一条狭长的纸带被均匀划分出了n个格子,格子编号从11到n。每个格子上都染了一种颜色colori​用[1,m]当中的一个整数表示),并且写了一个数字numberi​。

定义一种特殊的三元组:(x,y,z),其中x,y,z都代表纸带上格子的编号,这里的三元组要求满足以下两个条件:

  1. xyz是整数,x<y<z,y−x=z−y

  2. colorx=colorz

满足上述条件的三元组的分数规定为(x+z)×(numberx​+numberz​)。整个纸带的分数规定为所有满足条件的三元组的分数的和。这个分数可能会很大,你只要输出整个纸带的分数除以10,007所得的余数即可。

输入格式

第一行是用一个空格隔开的两个正整数n表式纸带上格子的个数,m表纸带上颜色的种类数。

第二行有n用空格隔开的正整数,第i数字number表纸带上编号为i格子上面写的数字。

第三行有n用空格隔开的正整数,第i数字color表纸带上编号为i格子染的颜色。

输出格式

一个整数,表示所求的纸带分数除以1000710007所得的余数。

输入输出样例

输入 #1复制

6 2
5 5 3 2 2 2
2 2 1 1 2 1

输出 #1复制

82

输入 #2复制

15 4
5 10 8 2 2 2 9 9 7 7 5 6 4 2 4
2 2 3 3 4 3 3 2 4 4 4 4 1 1 1

输出 #2复制

1388

说明/提示

【输入输出样例 1 说明】

纸带如题目描述中的图所示。

所有满足条件的三元组为: (1,3,5),(4,5,6)(1,3,5),(4,5,6)。

所以纸带的分数为(1+5)×(5+2)+(4+6)×(2+2)=42+40=82(1+5)×(5+2)+(4+6)×(2+2)=42+40=82。

对于第 11 组至第 22 组数据,1≤n≤100,1≤m≤5;

对于第33 组至第 44 组数据, 1≤n≤3000,1≤m≤100;

对于第 55 组至第66组数据, 1≤n≤100000,1≤m≤100000,且不存在出现次数超过20的颜色;

对 于 全 部 1010 组 数 据 , 1≤n≤100000,1≤m≤100000,1≤colori​≤m,1≤numberi​≤100000

从这道题里,我们可以学到很多东西。

因为每个格子的编号是从1开始的,所以我们定义两个数组,a【i】表示 第i个格子内的数字,

b【i】表示第i个格子的颜色。

然后,这道题给了我们一个三元组(x,y,z),三个编号为x,y,z的格子。

要求这个三元组满足下面两个条件:

第一个条件是,这个三元组内部是严格升序的,并且,y-x=z-y

严格升序都能理解,那么我们接下来研究一下y-x=z-y这个条件想表达什么。

首先呢,不难看出它是一个等差数列。即x,y,z满足等差性质

那么假设公差为d,则有:x+2d=z,因为2d是一个偶数,所以x必然与z共奇偶。

请把这条性质记住。我们为什么会想到这个呢?因为我们是站在枚举复杂度的角度来看的。

假设我们要找到所有满足条件的x,y,z,那么简单的三重枚举就行了,但是会超时。

所以我们必须要找出优化的枚举操作。并带着目的性去审视题目给的条件。

第二个条件是:在(x,y,z)中,编号x的格子颜色要等于,编号为z的格子的颜色

即b【x】=b【z】

足这两个条件的三元组就可以计入答案,

每一组合法的三元组对答案的贡献是(x+z)*(a【x】+a【z】)

那么这道题到这就结束了吗?

不,还远远没有。

因为以我们现在推出来的条件,我们需要每次枚举x,z的位置(复杂度为O(n^2)),并且判断x,z的奇偶性,颜色是否相同。

这样做仍然无法通过本题(没错就是这么变态)

所以我们还要优化,但是还有哪里能优化呢?我们已经优化了条件,但是你有没有想过,计算答案这个过程是可以优化的。

每一个合法的三元组对答案的贡献可以展开成:x*a【x】+x*a【z】+z*a【x】+z*a【y】

那么x对答案的贡献是什么呢?x*a【x】+x*a【z】

我们简化一下问题:不考虑颜色是否相同,只考虑奇偶性是否相同

假设一对合法三元组为(1,2,3)那么1对答案的贡献是 1*a【1】+1*a【3】;

然后枚举z,当x=1的时候,z可以是5,7,9,11,13......

所以1对答案的贡献就是:1*a【1】+1*a【3】)+(1*a【1】1*a【5】)+(1*a【1】+1*a【7】)......

假设z枚举到7为止,也就是说如果有4个条件相同的元素(1,3,5,7)那么

1对答案的贡献:    3* (1*a【1】)+a【3】+a【5】+a【7】

等价于: 2*(1*a【1】)+(a【1】+a【3】+a【5】+a【7】)

3对答案的贡献:    3*(3*a【3】)+ 3a【1】+3a【5】+3a【7】

等价于:    2*(3*a【3】)+ 3(a【1】+a【3】+a【5】+a【7】)

我们可以把这个化成i的时候的一般式子,即i对于答案的贡献是 ( 共奇偶的格子数-2)*a【1】+i*(所有的共奇偶的格子上的数字和)

那么把这个东西一般化呢?即 任何 i 对答案的贡献是 a【i】*(满足同一种条件的格子数-2)+i*(满足同一种条件的格子数上面的数字之和)

让我们回到我们的问题,合法的三元组必须满足颜色相同,奇偶相同的性质

所以我们可以同理推理出来: 任何i对答案的贡献都是 a【i】*(共奇偶,且共颜色 的格子的总个数-2)+i*(共奇偶,共颜色的格子上面的数字之和)

所以我们只需要提前算出,共奇偶且共颜色的每个格子上的数字之和,和共奇偶且共颜色的格子总数。

用一个数组来存《共奇偶且共颜色的每个格子上的数字之和》   那么就有前缀和式子: sum【颜色】【奇偶】+= 满足这个条件的格子上的数字

也就是 sum[b[i][i%2]+= a[i];

另一个数组来存《共奇偶且共颜色的格子总数》 有 桶排序 ans【颜色】【奇偶】++;

也就是ans[b[i]][i%2]++;

然后我们就可以线性地求答案了。

只需要枚举i=1~n,每次计算答案,然后取模就可以了 。

代码如下:


const int N = 1e5 + 10;
const int mod = 10007;
int sum, n, m;
int a[N], b[N];
int sum1[N][3];//同色同奇偶的个数
int num[N][3];//同色奇偶的编号和
int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++)cin >> a[i];//输入编号
	for (int i = 1; i <= n; i++)
	{
		cin >> b[i];
		sum1[b[i]][i % 2]++;
		num[b[i]][i % 2] = (num[b[i]][i % 2]+a[i]) % mod;
	}
	for (int i = 1; i <= n; i++)
	{ 
		sum = (sum+ i *( (sum1[b[i]][i % 2] - 2) * a[i]%mod + num[b[i]][i % 2]) )%mod;
	}
	cout << sum;
}



http://lihuaxi.xjx100.cn/news/1787246.html

相关文章

vue中如何将json数组指定的key赋值给el-form-item并均匀的分成2列

在Vue中&#xff0c;你可以使用v-for指令来遍历JSON数组&#xff0c;并将指定的key赋值给el-form-item。下面是一个示例&#xff1a; <template><el-form><el-row><el-col :span"6" v-for"item in jsonArray" :key"item.key&qu…

[运维工具]ubuntu下迁移home目录至新的分区教程详解

ubuntu下迁移home目录至新的分区教程详解 前言 首先声明一下&#xff0c;因为此教程涉及到用户重要资料数据&#xff0c;所以操作前&#xff1a; 数据无价&#xff0c;请一定要先备份&#xff01;数据无价&#xff0c;请一定要先备份&#xff01;数据无价&#xff0c;请一定…

JAVA数据代码示例

首先&#xff0c;我们需要导入一些必要的Java库 java import java.net.URL; import java.net.HttpURLConnection; import java.io.BufferedReader; import java.io.InputStreamReader; 然后&#xff0c;我们可以创建一个URL对象&#xff0c;表示我们要爬取的网页的URL。 jav…

智慧城市怎么实时监测内涝积水的发生及解决办法?

随着城市化进程步伐不断加快&#xff0c;城市内涝问题越来越受到人们的关注。内涝不仅不便于人们的生活&#xff0c;还可能危害城市之中的基础设施比如路面等。因此实时监测内涝积水的发生并采取有效的解决办法是市政府的紧急任务&#xff0c;同时解决城市内涝也利于城市生命线…

解决Dockerfile中 Could not initialize class sun.awt.X11FontManager错误

Dockerfile中增加命令 RUN yum install dejavu-sans-fonts fontconfig -y如果您使用的是基于Alpine Linux的发行版&#xff0c;可以使用apk命令来安装DejaVu Sans字体和fontconfig工具 RUN apk update RUN apk add ttf-dejavu fontconfig

Windows系统下使用docker部署redis

使用虚拟机部署redis&#xff0c;虚拟机很占用电脑资源&#xff0c;所以选择使用docker对redis进行部署。 一、安装docker 安装链接&#xff1a;https://docker.p2hp.com/ 二、配置redis.conf文件 下载配置文件&#xff1a;https://download.redis.io/redis-stable/redis.con…

高教社杯数模竞赛特辑论文篇-2023年A题:定日镜场的输出功率优化(附获奖论文及MATLAB代码实现)(中)

目录 6.4定日镜平均输出热功率优化模型的求解 6.5问题二求解结果 6.6 结果分析

vSphere进入维护模式

在vSphere中&#xff0c;当您将主机置于维护模式时&#xff0c;虚拟机通常会根据您的设置自动迁移。vSphere提供了不同的维护模式选项&#xff0c;包括&#xff1a; 自动迁移虚拟机&#xff1a;如果您选择将主机置于"维护模式"&#xff0c;并启用了VMware vSphere Di…