COCI2022-2023#1 Neboderi

news/2024/7/23 10:25:11 标签: 题解, c++

P9032 [COCI2022-2023#1] Neboderi

题目大意

有一个长度为 n n n的序列 h i h_i hi,你需要从中选择一个长度大于等于 k k k的子区间 [ l , r ] [l,r] [l,r],使得 g × ( h l + h l + 1 + ⋯ + h r ) g\times (h_l+h_{l+1}+\cdots+h_r) g×(hl+hl+1++hr)最小,其中 g = gcd ⁡ ( h l , h l + 1 , … , h r ) g=\gcd(h_l,h_{l+1},\dots,h_r) g=gcd(hl,hl+1,,hr)

1 ≤ k ≤ n ≤ 1 0 6 , 1 ≤ h i ≤ 1 0 6 1\leq k\leq n\leq 10^6,1\leq h_i\leq 10^6 1kn106,1hi106


题解

当确定了 l l l时, gcd ⁡ ( h l , h l + 1 , … , h r ) \gcd(h_l,h_{l+1},\dots,h_r) gcd(hl,hl+1,,hr)随着 r r r的增大而减小。

每当 gcd ⁡ \gcd gcd减小时,其 gcd ⁡ \gcd gcd相对于原来的 gcd ⁡ \gcd gcd肯定有若干个质因数的次数减小。那么,对于一个确定的 l l l gcd ⁡ ( h l , h l + 1 , … , h r ) \gcd(h_l,h_{l+1},\dots,h_r) gcd(hl,hl+1,,hr)的取值不会超过 log ⁡ a l \log a_l logal个数。

先用 S T ST ST表维护区间 gcd ⁡ \gcd gcd。枚举 l l l,在二分每一段 g c d gcd gcd值相等的区间并取该区间的右端点作为 r r r来更新答案。

v v v a i a_i ai的最大值,则时间复杂度为 O ( n log ⁡ n log ⁡ v ) O(n\log n\log v) O(nlognlogv)

当然,这是跑不满的,而且时限为 2.50 s 2.50s 2.50s,所以可以过。


code

#include<iostream>
#include<cstdio>
using namespace std;
const int N=1000000;
int n,k,now,v[N+5],lg[N+5],f[N+5][20];
long long ans=0,sum[N+5];
int gcd(int i,int j){
	while(j){
		i%=j;swap(i,j);
	}
	return i;
}
int gt(int l,int r){
	int x=lg[r-l+1];
	return gcd(f[l][x],f[r-(1<<x)+1][x]);
}
int to(int w,int be,int hv){
	int l=be+1,r=n,mid;
	while(l<=r){
		mid=l+r>>1;
		if(gt(w,mid)>=hv) l=mid+1;
		else r=mid-1;
	}
	return l-1;
}
int main()
{
	scanf("%d%d",&n,&k);
	lg[0]=-1;
	for(int i=1;i<=n;i++){
		lg[i]=lg[i/2]+1;
		scanf("%d",&v[i]);
		sum[i]=sum[i-1]+v[i];
		f[i][0]=v[i];
	}
	for(int i=1;i<=19;i++){
		for(int j=1;j<=n-(1<<i-1);j++){
			f[j][i]=gcd(f[j][i-1],f[j+(1<<i-1)][i-1]);
		}
	}
	for(int l=1,r;l<=n-k+1;l++){
		now=gt(l,l+k-1);
		r=to(l,l+k-1,now);
		while(r<=n){
			ans=max(ans,gt(l,r)*(sum[r]-sum[l-1]));
			if(r==n) break;
			now=gt(l,r+1);
			r=to(l,r+1,now);
		}
	}
	printf("%lld",ans);
	return 0;
}

http://www.niftyadmin.cn/n/5066792.html

相关文章

CUDA C编程权威指南:1-基于CUDA的异构并行计算

什么是CUDA&#xff1f;CUDA&#xff08;Compute Unified Device Architecture,统一计算设备架构&#xff09;是NVIDIA&#xff08;英伟达&#xff09;提出的并行计算架构&#xff0c;结合了CPU和GPU的优点&#xff0c;主要用来处理密集型及并行计算。什么是异构计算&#xff1…

华为云云耀云服务器L实例评测|基于canal缓存自动更新流程 SpringBoot项目应用案例和源码

前言 最近华为云云耀云服务器L实例上新&#xff0c;也搞了一台来玩&#xff0c;期间遇到各种问题&#xff0c;在解决问题的过程中学到不少和运维相关的知识。 在之前的博客中&#xff0c;介绍过canal的安装和配置&#xff0c;参考博客 拉取创建canal镜像配置相关参数 & …

Tomcat在CentOS上的安装部署

目录 1. Tomcat简介 2. 安装 2.1 安装JDK环境 2.1.1 下载JDK软件 2.1.2 登陆Linux系统&#xff0c;切换到root用户 2.1.3 通过FinalShell&#xff0c;上传下载好的JDK安装包 2.1.4 创建文件夹&#xff0c;用来部署JDK&#xff0c;将JDK和Tomcat都安装部署到&#…

LeetCode 251:展开二维向量

题目 Implement an iterator to flatten a 2d vector. Example: [1,2,3,4,5,6] [1,2,3,4,5,6] Follow up: As an added challenge, try to code it using only iterators in C++ or iterators in Java. 题解: 用两个index 分别记录list 的 index 和当前 list的element index. …

vcpkg切换 Visual Studio 版本

vcpkg切换 Visual Studio 版本 在使用vcpkg作为项目的包管理工具时&#xff0c;可能会遇到需要切换Visual Studio版本的情况。下面是一种简单的方法来实现这个目标&#xff0c;通过修改triplet文件来指定使用的Visual Studio版本。 步骤1: 创建或修改Triplet文件 首先&#…

Python:操作SQLite数据库简单示例

本文用最简单的示例演示python标准库提供的SQLite数据库进行新增、查询数据的过程。 代码文件app.py # -*- coding: UTF-8 -*- from flask import Flask import sqlite3app Flask(__name__)app.route(/) def hello_world():return Hello World!#创建数据库 app.route(/creat…

Python中Lambda用法

在Python中&#xff0c;lambda函数是一种形式较短的函数&#xff0c;又称为匿名函数。与正常的函数不同&#xff0c;lambda函数没有名称&#xff0c;因此只能在定义时直接传递给其他函数或变量使用&#xff0c;而不能单独调用。 lambda函数的语法非常简单&#xff0c;格式如下…

uboot启动流程-uboot内存分配工作总结

一. uboot 启动流程 _main 函数中会调用 board_init_f 函数&#xff0c;本文继续简单分析一下 board_init_f 函数。 本文继续具体分析 board_init_f 函数。 本文继上一篇文章的学习&#xff0c;地址如下&#xff1a; uboot启动流程-uboot内存分配_凌肖战的博客-CSDN博客 二…