首页 > 其他分享 >单峰数列

单峰数列

时间:2024-07-28 21:07:28浏览次数:14  
标签:va rv 数列 int mid bj 单峰 long

  • 用线段树维护原序列对应的差分数组,可以把区间修改简化为单点修改
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int a[100005],n;
int read1()
{
	char cc=getchar();
	while(!(cc>=48&&cc<=57))
	{
		if(cc=='-')
		{
			break;
		}
		cc=getchar();
	}
	bool f=false;
	int s=0;
	if(cc=='-')
	{
		f=true;
	}
	else
	{
		s=cc-48;
	}
	while(1)
	{
		cc=getchar();
		if(cc>=48&&cc<=57)
		{
			s=s*10+cc-48;
		}
		else
		{
			break;
		}
	}
	if(f==true)
	{
		s=-s;
	}
	return s;
}
struct t1
{
	int l,r;
	long long u,v,bj;
	bool fs,fu,fd;
	long long va;
}t[400005];
void update(int p)
{
	t[p].u=t[p*2].u;t[p].v=t[p*2+1].v;
	t[p].fu=(t[p*2].fu&&t[p*2+1].fu&&t[p*2].v<t[p*2+1].u);
	t[p].fd=(t[p*2].fd&&t[p*2+1].fd&&t[p*2].v>t[p*2+1].u);
	long long lv=t[p*2].va,rv=t[p*2+1].va;
	t[p].fs=(lv==rv&&t[p*2].fs&&t[p*2+1].fs);
	if(t[p].fs)
	{
		t[p].va=lv;
	}
	else
	{
		t[p].va=-1;
	}
}
void spread(int p)
{
	long long bj=t[p].bj;
	t[p].bj=0;
	t[p*2].bj+=bj;
	t[p*2+1].bj+=bj;
	t[p*2].u+=bj;t[p*2].v+=bj;
	t[p*2+1].u+=bj;t[p*2+1].v+=bj;
	if(t[p*2].fs)
	{
		t[p*2].va+=bj;
	}
	if(t[p*2+1].fs)
	{
		t[p*2+1].va+=bj;
	}
}
void build(int p,int l,int r)
{
	t[p].l=l;
	t[p].r=r;
	if(l==r)
	{
		t[p].va=t[p].u=t[p].v=a[l];
		t[p].fs=t[p].fu=t[p].fd=true;
		return;
	}
	int mid=(l+r)>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	update(p);
}
bool asks(int p,int l,int r)
{
	if(l<=t[p].l&&r>=t[p].r)
	{
		return t[p].fs;
	}
	spread(p);
	int mid=(t[p].l+t[p].r)>>1;
	bool va=true;
	long long lv,rv;
	if(l<=mid)
	{
		va=va&asks(p*2,l,r);
		lv=t[p*2].v;
	}
	if(r>mid)
	{
		va=va&asks(p*2+1,l,r);
		rv=t[p*2+1].u;
	}
	if(l<=mid&&r>mid)
	{
		va=va&(lv==rv);
	}
	return va;
}
bool asku(int p,int l,int r)
{
	if(l<=t[p].l&&r>=t[p].r)
	{
		return t[p].fu;
	}
	spread(p);
	int mid=(t[p].l+t[p].r)>>1;
	bool va=true;
	long long lv,rv;
	if(l<=mid)
	{
		va=va&asku(p*2,l,r);
		lv=t[p*2].v;
	}
	if(r>mid)
	{
		va=va&asku(p*2+1,l,r);
		rv=t[p*2+1].u;
	}
	if(l<=mid&&r>mid)
	{
		va=va&(lv<rv);
	}
	return va;
}
bool askd(int p,int l,int r)
{
	if(l<=t[p].l&&r>=t[p].r)
	{
		return t[p].fd;
	}
	spread(p);
	int mid=(t[p].l+t[p].r)>>1;
	bool va=true;
	long long lv,rv;
	if(l<=mid)
	{
		va=va&askd(p*2,l,r);
		lv=t[p*2].v;
	}
	if(r>mid)
	{
		va=va&askd(p*2+1,l,r);
		rv=t[p*2+1].u;
	}
	if(l<=mid&&r>mid)
	{
		va=va&(lv>rv);
	}
	return va;
}
void change(int p,int l,int r,int x)
{
	if(l<=t[p].l&&r>=t[p].r)
	{
		t[p].bj+=x;
		t[p].u+=x;
		t[p].v+=x;
		if(t[p].fs)
		{
			t[p].va+=x;
		}
	}
	else
	{
		spread(p);
		int mid=(t[p].l+t[p].r)>>1;
		if(l<=mid)
		{
			change(p*2,l,r,x);
		}
		if(r>mid)
		{
			change(p*2+1,l,r,x);
		}
		update(p);
	}
}
int main()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		a[i]=read1();
	}
	build(1,1,n);
	int q;
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		int opt,l,r;
		opt=read1();
		l=read1();
		r=read1();
		if(opt==1)
		{
			int x=read1();
			change(1,l,r,x);
		}
		else if(opt==2)
		{
			printf("%d\n",asks(1,l,r));
		}
		else if(opt==3)
		{
			printf("%d\n",asku(1,l,r));
		}
		else if(opt==4)
		{
			printf("%d\n",askd(1,l,r));
		}
		else if(opt==5)
		{
			int tl=l,tr=r;
			l++;
			r--;
			bool pd=true;
			while(l<r)
			{
				int mid=(l+r)>>1;
				bool pl=asku(1,tl,mid);
				bool pr=askd(1,mid,tr);
				if(pl==pr&&pr==true)
				{
					break;
				}
				else if(pl==true)
				{
					l=mid+1;
				}
				else if(pr==true)
				{
					r=mid-1;
				}
				else
				{
					pd=false;
					break;
				}
			}
			if(l>r)
			{
				pd=false;
			}
			else if(l==r)
			{
				pd=(asku(1,tl,l)&askd(1,r,tr));
			}
			printf("%d\n",pd);
		}
	}
	return 0;
}

标签:va,rv,数列,int,mid,bj,单峰,long
From: https://www.cnblogs.com/watersail/p/18328867

相关文章

  • 航电第三场(单峰数列)
    单峰数列题意对于一个整数数列,如果其先严格递增,然后在某一点后严格递减,我们称这个数列为单峰数列(严格递增和严格递减的部分均要是非空)。给定长度为n的整数数列\(a_1,a_2,…,a_n\),请你支持q次操作:1lrx:将\(a_l,a_{l+1},…,a_r\)的每个数加x。2lr:判断\(a_l,a_{l......
  • 优美子数列2 题解
    题目id:8628题目描述数学家小\(Q\)得到了一个长度为\(N\)的数列\(a_n\)。小\(Q\)的幸运数字是\(k\),所以他认为,若一个子数列\(a_l,a_{l+1},...,a_r\)的和为\(k\)的倍数,则该子数列是优美子数列。小\(Q\)现在想考考你,\(a_n\)里有多少个优美子数列呢?前置知识前缀和、桶解题思路......
  • 在整数列表中查找最长的重复非重叠整数序列
    我需要一个有效的代码来查找整数列表中最长的非重叠整数序列。我到处寻找,甚至询问了GPT4o,但没有找到解决这个相当简单但有趣的问题的好方法。如果有人可以帮助我改进它并检查它的准确性,我真的很感激!提前致谢。这是我到目前为止所得到的。这是非常低效和缓慢的,但......
  • C++(构造函数参数列表初始化)
    目录1.构造函数参数列表初始化的语法2.为什么使用参数列表初始化3.示例4.常量和引用成员的示例5.使用参数列表初始化的注意事项6.总结在C++中,构造函数参数列表初始化(initializerlist)是一种用于在对象创建时初始化成员变量的语法。这种方式在性能和可读性方面具有一些优势,......
  • 函数传参,递归函数(汉诺塔,裴波那契数列),预处理
    递归函数 获得斐波那契数列的第n项的值斐波那契数列是指这样一个数列:1,1,2,3,5,8,13,21,34,55,89……这个数列从第3项开始,每一项都等于前两项之和。#include<stdio.h>intFbnq(intn){if(n==1){return1;}elseif(n==2){return1......
  • 意外的函数行为关键参数列表构造函数
    我已经将这个简单的代码简化为更大的python代码中的意外行为:deff(n,s=[]):s.append(n)returnsprint(f(3))print(f(5))给出的输出是:[3][3,5]我期望:[3][5]如果明确给出空列表作为参数,则f(5,s=[]),它按预期工作。我认为这是一个不好的做法,......
  • 题解 B3694 数列离散化
    link简而言之,离散化就是把一个数列转化为由小到大的排名来缩小范围。离散化需要这个题不用数字本身。举个例子:-200244879914993235793离散化后就是:15243\(-2002\)最小,所以它对应\(1\)\(448799\)最大,所以它对应\(5\)实现考虑如何实现。首先由于离散化前后......
  • Leetcoede编程基础0到1——459.重复的子字符串 & 283.移动零 &1822.数组元素积的符号
    459.重复的子字符串给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。示例1:输入:s="abab"输出:true解释:可由子串"ab"重复两次构成。示例2:输入:s="aba"输出:false示例3:输入:s="abcabcabcabc"输出:true解释:可由子......
  • 将具有最接近值的整数列表分组
    我有一个列表:d=[23,67,110,25,69,24,102,109]如何将最近的值与动态间隙分组,并创建这样的元组,最快的方法是什么?:[(23,24,25),(67,69),(102,109,110)]defgroup_close_integers(data,gap):"""将具有最接近值的整数列表分组。参数:data:要分......
  • P1182 数列分段 Section II
    传送锚点:数列分段SectionII-洛谷题目描述对于给定的一个长度为\(N\)的正整数数列\(A_{1\simN}\),现要将其分成\(M\)(\(M\leqN\))段,并要求每段连续,且每段和的最大值最小。关于最大值最小:例如一数列\(4\2\4\5\1\)要分成\(3\)段。将其如下分段:\([4\2][4\5][1......