2021牛客多校第二场 A——Arithmetic Progression

网易2018校招编程题集合2 如果一个数列S满足对于所有的合法的i,都有S[i + 1] = S[i] + d, 这里的d也可以是负数和零,我们就称数列S为等差数列。 小易现在有一个长度为n的数列x,小易想把x变为一个等差数列。小易允许在数列上做交换任意两个位置的数值的操作,并且交换操作允许交换多次。但是有些数列通过交换还是不能变成等差数列,小易需要判别一个数列是否能通过交换操作变成等差数列  输入描述: 输入包 阅读详情

题目大意

给你一个长度为 nnn 的数列 aaa ,数列中每个元素都不一样,问你存在多少个区间,这些区间内的数排序后是一个等差数列

解题思路

对于一个区间,如果这个区间内的数排序后的元素可以构成一个等差序列,那么一定满足下列性质
max−min=(r−l)×gcdmax - min = (r - l) \times gcdmax−min=(r−l)×gcd
其中 gcdgcdgcd 是区间差分绝对值的最大公约数
minminmin 是区间的最小值
maxmaxmax 是区间的最大值
我们做这题的思想是,枚举右端点,用数据结构维护有多少个合法的左端点
我们用一个线段树来维护这个东西。线段树一个节点维护四个值
dat:max−min−(r−l)×gcddat: max-min-(r-l)\times gcddat:max−min−(r−l)×gcd的最小值,右端点为我们枚举的右端点(因为这个式子的最小值为0,当这个值为0时,说明这是一个合法的区间)
cnt:cnt:cnt:合法左端点的个数
add:add:add:懒标记
g:g:g:当前节点所代表区间的差分的绝对值的最大公约数
这样我们每次询问区间 [1,r][1, r][1,r] 就可以知道有多少个合法的区间

接下来我们考虑右端点往右移(即新加一个数)的情况。
新加入一个数,可能对之前的 minminmin 和 maxmaxmax 有影响,为了解决这个问题,我们用单调栈解决。

我们对于 minminmin 维护一个上升的单调栈,栈里面存下标
如果新加入的元素比栈顶大,那么直接入栈,它不会对之前区间的 minminmin 产生影响。
如果新加入的元素小于等于栈顶元素,那么我们将区间 [[[ 栈顶第二个元素+1, 栈顶元素 ]]] 都加上栈顶元素下标所在的值(这一步是为了消除栈顶元素的影响)
弹出栈顶元素,直到当前元素比栈顶元素大,否则一直执行上述步骤。
然后将区间 [[[栈顶元素+1, 当前枚举的右端点 ]]] 减去当前元素(这一步是为了加上这新元素的影响)
对于 maxmaxmax 维护一个下降的单调栈,与上述操作类似,不再赘述。

我们维护完了最大最小值,我们再维护 (r−l)×gcd(r-l)\times gcd(r−l)×gcd。我们记 d=∣ai−1−ai∣d = |a_{i-1} - a_i|d=∣ai−1​−ai​∣,我们更新区间 [1,r−1][1, r-1][1,r−1]

当区间的 ggg 满足 g!=0&& d∣gg != 0 \&\& \ d|gg!=0&& d∣g时,说明这个区间新加入这个数是能维持 ggg 不变的,所以我们新加入一个数的影响是将这个区间的值减去一个 ggg (因为区间长度变长了,所以要减去一个 ggg 如果不懂再看看 datdatdat 的定义)
如果不满足上述条件,我们需要将之间的(r−l)∗g(r-l) * g(r−l)∗g加上(消去之前的影响),再将 g=gcd(g,d)g = gcd(g, d)g=gcd(g,d),然后减去(r−l)∗g(r-l) * g(r−l)∗g,(加上这个数的影响)

Code

#include <bits/stdc++.h>
#define ll long long
#define qc ios::sync_with_stdio(false); cin.tie(0);cout.tie(0)
#define fi first
#define se second
#define PII pair<int, int>
#define PLL pair<ll, ll>
#define pb push_back
using namespace std;
const int MAXN = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
    while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
int n;
int stmi[MAXN], stma[MAXN];
ll a[MAXN];
ll gcd(ll a, ll b){
	return b ? gcd(b, a%b) : a;
}
struct Tree{
	int l, r;
	ll dat, g, add, cnt;
}tree[MAXN << 2];
void pushup(int rt){
	tree[rt].cnt = 0;
	tree[rt].dat = min(tree[rt << 1].dat, tree[rt << 1 | 1].dat);
	if(tree[rt].dat == tree[rt << 1].dat)
		tree[rt].cnt += tree[rt << 1].cnt;
	if(tree[rt].dat == tree[rt << 1 | 1].dat)
		tree[rt].cnt += tree[rt << 1 | 1].cnt;
	if(tree[rt << 1].g && tree[rt << 1 | 1].g && tree[rt << 1].g == tree[rt << 1 | 1].g)
		tree[rt].g = tree[rt << 1].g;
	else
		tree[rt].g = 0;
}
void build(int l, int r, int rt){
	tree[rt].l = l;
	tree[rt].r = r;
	tree[rt].cnt = tree[rt].add = tree[rt].g = tree[rt].dat = 0ll;
	if(l == r){
		tree[rt].cnt = 1ll;
		return ;
	}
	int m = (l + r) >> 1;
	build(l, m, rt << 1);
	build(m+1, r, rt << 1 | 1);
	pushup(rt);
}
void pushdown(int rt){
	if(tree[rt].add){
		tree[rt << 1].dat += tree[rt].add;
		tree[rt << 1].add += tree[rt].add;
		tree[rt << 1 | 1].dat += tree[rt].add;
		tree[rt << 1 | 1].add += tree[rt].add;
		tree[rt].add = 0;
	}
}
void update(int L, int R, ll val, int rt){
	if(L <= tree[rt].l && tree[rt].r <= R){
		tree[rt].dat += val ;
		tree[rt].add += val;
		return;
	}
	pushdown(rt);
	int m = (tree[rt].l + tree[rt].r) >> 1;
	if(L <= m)
		update(L, R, val, rt << 1);
	if(m < R)
		update(L, R, val, rt << 1 | 1);
	pushup(rt);
}
void updateGcd(int R, int l, int r, ll g, int rt){
	if(l <= tree[rt].l && tree[rt].r <= r && tree[rt].g && g % tree[rt].g == 0){
			tree[rt].dat -= tree[rt].g;
			tree[rt].add -= tree[rt].g;
	}
	else if (tree[rt].l == tree[rt].r){
			tree[rt].dat += (R - tree[rt].l - 1) * tree[rt].g;
			tree[rt].add += (R - tree[rt].l - 1) * tree[rt].g;
			tree[rt].g = gcd(g, tree[rt].g);
			tree[rt].dat -= (R - tree[rt].l) * tree[rt].g;
			tree[rt].add -= (R - tree[rt].l) * tree[rt].g;
	}
	else{
		pushdown(rt);
		int m = (tree[rt].l + tree[rt].r) >> 1;
		if(l <= m)
			updateGcd(R, l, r, g, rt << 1);
		if(m < r)
			updateGcd(R, l, r, g, rt << 1 | 1);
		pushup(rt);
	}
	
}
ll query(int L, int R, int rt){
	if(L <= tree[rt].l && tree[rt].r <= R){
		return tree[rt].dat == 0 ? tree[rt].cnt : 0;
	}
	pushdown(rt);
	int m = (tree[rt].l + tree[rt].r) >> 1;
	ll ret = 0;
	if(L <= m)
		ret += query(L, R, rt << 1);
	if(m < R)
		ret += query(L, R, rt << 1 | 1);
	return ret;
}
void solve(){
    scanf("%d",&n);
    for(int i = 1; i <= n; i++)
    	scanf("%lld", a+i);
    ll ans = 0;
    build(1, n, 1);
    int topmi = 0, topma = 0;
    for(int i = 1; i <= n; i++){
    	while(topmi && a[stmi[topmi]] > a[i]){
    		update(stmi[topmi - 1] + 1, stmi[topmi], a[stmi[topmi]], 1);
    		topmi--;
    	}
    	update(stmi[topmi] + 1, i, -a[i], 1);
    	stmi[++topmi] = i;
    	while(topma && a[stma[topma]] < a[i]){
    		update(stma[topma - 1] + 1, stma[topma], -a[stma[topma]], 1);
    		topma--;
    	}
    	update(stma[topma] + 1, i, a[i], 1);
    	stma[++topma] = i;
    	if(i != 1){
    		updateGcd(i, 1, i-1, abs(a[i] - a[i-1]), 1);
    	}
    	ans += query(1, i, 1);
    }
    printf("%lld\n",ans);
}

int main()
{
	#ifdef ONLINE_JUDGE
    #else
       freopen("in.txt", "r", stdin);
       freopen("out.txt", "w", stdout);
    #endif

	// qc;
    int T;
    // cin >> T;
    scanf("%d",&T);
    // T = 1;
    while(T--){

        solve();
    }
	return 0;
}
Win10自动更新怎么永久关闭?有效的Win10强制更新关闭方法 之前小编为大家分享过一些Win10彻底关闭Windows Update自动更新的方法,主要是通过一些如设置流量计费或借助一些专门的小工具来实现,但往往会发现,Win10自动更新就像打不死的小强,不管怎么关闭,之后还是会自动更新,让不少小伙伴颇为不爽。今天小编带来了这篇改进型教程,通过全方位设置,彻底关闭Win10自动更新,感兴趣的小伙伴不妨试试吧。 ... 阅读详情

相关推荐

激光测距仪DIY指南:从元器件选型到精度优化(附避坑清单)

本文提供了一份详尽的激光测距仪DIY实战指南,涵盖从核心元器件选型到系统集成的全过程。重点解析了相位法测距原理,并分享了激光发射器与APD探测器选型、信号链路设计、低成本改造方案以及精度校准等关键环节的避坑经验,帮助电子爱好者与开发者深入理解并成功搭建高精度测距系统。

h6i7j8的博客 944

bzoj 4373: 算术天才⑨与等差数列

Description 算术天才⑨非常喜欢和等差数列玩耍。 有一天,他给了你一个长度为n的序列,其中第i个数为a[i]。 他想考考你,每次他会给出询问l,r,k,问区间[l,r]内的数从小到大排序后能否形成公差为k的等差数列。 当然,他还会不断修改其中的某一项。 为了不被他鄙视,你必须要快速并正确地回答完所有问题。 注意:只有一个数的数列也是等差数列。 Input 第一

lqybzx的专栏 1096

嵌入式开发 DSP芯片运行方式(挖坑-填坑中-坑已平 :))

TMS320F28335 DSP 芯片 如何将运行代码放在不同的位置

FOOLCODE的专栏 1306

n个整数中,找出尽可能多的数使他们组成一个等差数列,求最长等差数列的长度...

例子: 3,8,4,5,6,2 返回值应该为 :5 这是昨天做的一道优酷土豆的编程题,和leetcode中的128/Longest Consecutive Sequence 有点相似,但是leetcode题的公差是确定的1,而这道题的公差是不确定的。 本人的写出的是一种通过穷举的方法实现查找最长等差数列,通过hash使查找更为方便,减少了复杂度。 int ca...

weixin_34185560的博客 625

(10)Proteus 8.9上的STM32仿真系列(HAL)---freertos

实验设计:通过cubemxide生成freertos工程,然后创建一个 pc13 led灯间隔200ms闪烁的任务。非常遗憾的是proteus8.9仿真失败,实物上没有问题,但还是把流程过一遍。 一、原理图 实物是淘宝上stm32f103 c8t6的核心板,proteus上没有这个芯片,这里图上大概表示一下,用的是核心板自带的pc13引脚的led灯。 二、cubemxide配置 1.RCC如之前工程一样配置 2、配置SYS timebase Source不要使用systick,自己选择一个定时器,我这

qq_35442550的博客 7342

Fluent动网格+滑移网格+重叠网格对比介绍(以震荡水翼flapping foil为例)

初学fluent笔记,本文主要包含: Flapping foil在fluent内的几种实现方式 在哪设置动网格、滑移、重叠网格 flapping的UDF 示例 写在前面:Fluent在预览网格运动/提交计算之前,注意保存一个cas版本。 -------------------------Flapping foil 网格几种组合实现方式:---------------------- 直接重叠网格,overset, 需要建立两个几何part,part要重合。水翼局部区域(component),背景网格(ba

深海民工CFDer 2万+

【等差数列】题解

Link 给你一个长为 nnn,首项为 aaa,公差为 ddd 的等差数列。 从 xxx 中任选两个数 xi,xjx_i,x_jxi​,xj​ ,同时满足: xi+xjx_i+x_jxi​+xj​ 为偶数。 xxx 中没有 xi+xj2\frac{x_i+x_j}{2}2xi​+xj​​ 那么你就可以将 xi+xj2\frac{x_i+x_j}{2}2xi​+xj​​ 加入 xxx 中,称为一次操作。 注意:新加入的数也可被选择。 问你最多能进行几次操作? 蒟蒻第一次打月赛,激动地点开第一题:

qq_66589321的博客 705

大白话,Android Studio安装及其资源分享(离线gradle配置)

安装AndroidAtudio,并通过aliClound镜像与离线gradle配置,来跳过相对“繁文缛节”的过程,直接实现开发

wangzixuanemp的博客 3598

2018 河北省大学生程序设计竞赛

problem d:ch给你一个长度为n的数列,有两种操作:1.set  l  r  x :将[l,r]内的数全部赋值为x;2.query  l  r ;查询[l,r]中占主导地位的数字是哪个;该数字占主导地位指:该数在该区间中出现的此时占了区间长度的一半以上(出现一半不算占主导地位)。若没有,输出-1.input:第一行,一个数:n,表示序列的长度(1&lt;=n&lt;=200000);第二行...

Wild_Will的博客 3747

AXI VIP配置全指南:从报错到成功仿真的完整流程(Vivado 2023版)

本文详细解析了在Vivado 2023环境中配置AXI Verification IP(VIP)进行协议仿真的完整流程。针对常见的include和import报错问题,提供了具体的解决方案和代码示例,指导用户从IP核创建、参数化配置,到构建可工作的仿真测试平台,最终实现成功仿真。

gpt4scribbler的博客 233

中兴SDH设备开局及业务配置

中兴SDH设备开局及业务配置 1.设备开局(S200-----S325) A.开电之后,按住截铃(bell off)开关,直至NCP告警灯变成橙色; B.此时,设备进入Download状态,设备IP为:192.192.192.11/24; 2.用交叉线(568A)将设备的QX口连接至电脑,电脑配置和设备相同网段的IP信息; 3.在电脑上测试连通性:pin...

weixin_33897722的博客 3996

2021牛客暑假多校第二场部分题解

C-Draw Grids 题意:给你一个n*m的点矩阵,每次可以连相邻两个点的一条边,直到连完无法操作的时候就输了,前提是不能连成一个多边形。问你第一个人能不能赢 思路:就是按照竖直的线走到头,然后拐回去,直到最后连玩取余2看是谁走最后一步了。 代码: #include<bits/stdc++.h> using namespace std; typedef long long ll; int main () { ll n,m;cin>>n>>m; l

lvy_yu_ET的博客 561

【K8S系列】在 Kubernetes 中使用 Prometheus 进行监控的详细指南

Prometheus 是一个开源的监控和报警工具,广泛用于 Kubernetes 环境中。本文将深入探讨如何通过 Kubernetes 中的注解配置 Prometheus 的抓取设置,以高效监控服务,并确保系统的可靠性和可维护性。

颜淡慕潇 2万+

2021牛客暑期多校训练营2,签到题CDFKI

2021牛客暑期多校训练营2 题号 标题 已通过代码 通过率 团队的状态 A Arithmetic Progression 点击查看 6/72 未通过 B Cannon 点击查看 34/104 未通过 C Draw Grids 点击查看 1537/2307 通过(结论-奇偶性) D Er Ba Game 点击查看 1588/3007 通过(模拟) E Gas Station 点击查看 1/20 未通过 F Girlfriend 点击查看 620/3053 通过(计算几何) G League of Le

小哈里的博客 930

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

2022牛客多校2 J-Link with Arithmetic Progression

示例1。

weixin_54562114的博客 405

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

2022牛客多校训练第二场 J题 Link with Arithmetic Progression

三分

m0_51171995的博客 382

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

2021牛客暑期多校训练营2

2021牛客暑期多校训练营2 题号 题目 知识点 A Arithmetic Progression B Cannon C Draw Grids D Er Ba Game E Gas Station F Girlfriend G League of Legends H Olefin I Penguins bfs J Product of GCDs K Stack L WeChat Walk ...

qq_35975367的博客 395

[三分][最小二乘法]Link with Arithmetic Progression 2022牛客多校第2场 J

给出一个长度为n的数组,现在对于每个数ai都可以将其变为另一个数bi,该次操作代价为二者差值的平方,求令数组a成为等差数列所需要的最小代价。另外这道题目还可以用最小二乘法来拟合直线,这个方法据说是官方正解,但感觉还是比较难想到的。这道题目和去年济南站D题很像,...

Cloth的博客 522

“蔚来杯“2022牛客暑期多校赛 第二场 J-Link with Arithmetic Progression

“蔚来杯“2022牛客暑期多校赛 第二场 J-Link with Arithmetic Progression

weixin_69232161的博客 321

“蔚来杯“2022牛客暑期多校训练营2 个人题解集合

显然要生成无限物品,需要存在一个环且沿该环生成一轮得到的物品数目比原来更多,即为环上满足所有的边有。显然可以二分答案来做。那么可以分上下两个过程,分别存下所有的端点(带标记),每个乘客分配的轮数可以通过。首先枚举插入的括号数量,原来的括号序列和左括号比右括号多的数量。,即左括号的数量大于右括号的数量,并且使用的原括号的数量。的括号序列(不保证合法性),求在此基础上生成的长度为。如果目前枚举到的括号为左括号,并且使用的原括号的数量。如果此时枚举到的是一个右括号,并且。、使用的原来的序列中的括号数量为。...

HeartFireY的博客 991

Atcoder ABC340 A - Arithmetic Progression

Atcoder ABC340 A - Arithmetic Progression题解

2302_76207485的博客 640

牛客多校-Link with Arithmetic Progression-(三分总结)

就是给你一个数组,然后你每次可以让一个数a变为另一个数b,花费为(a-b)×(a-b)。然后问你让这个数组变成等差序列的最小花费。就是给你一个数组,每次你可以让一个数加1或者减1,然后把这个数组变成等差序列的最小花费。......

m0_52398496的博客 379

Almost Arithmetic Progression

A. Almost Arithmetic Progression time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard output Polycarp likes arithmetic progressions. A sequence [a1,a2,…,an...

代码演奏家 657

Arithmetic Progression

“In mathematics, an arithmeticprogression (AP) or arithmetic sequence is a sequence of numbers such that thedifference between the consecutive terms is constant. For instance, thesequence 5, 7, 9, 11,

Pis_arc的专栏 688

Arithmetic Progression解题报告

题目摘要:“In mathematics, an arithmeticprogression (AP) or arithmetic sequence is a sequence of numbers such that thedifference between the consecutive terms is constant. For instance, thesequence 5, 7, 9

卫少的专栏 1400

D. Almost Arithmetic Progression

D. Almost Arithmetic Progressiontime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputPolycarp likes arithmetic progressions. A sequence [a1,a2,…,an][a1,...

Swust_ZzK的博客 1375
上一篇: POJ2796 Feel Good——单调栈
下一篇: 2021牛客多校第二场 B——Cannon
Linda_yezi_coder
博客等级 码龄7年 20粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值