Cly的三角形 (思维+斐波那契)

题目链接:点击这里

题目大意:
给出一个长度为 n n n 的序列 a a a ,有 q q q 次询问,每次询问含有一组 l , r l,r l,r a l a_l al a r a_r ar 中是否能找出三条边使之构成三角形

题目分析:
我们先从暴力出发,我们发现:
对于一次询问的 l , r l,r l,r 我们将 a l a_l al a r a_r ar 进行从小到大的排序,然后逐个枚举相邻三个的元素,如果满足 a [ i ] + a [ i + 1 ] > a [ i + 2 ] a[i]+a[i+1]>a[i+2] a[i]+a[i+1]>a[i+2] 则可以构成三角形,如果 a [ i ] a[i] a[i] a [ i + 1 ] a[i+1] a[i+1] 都不能和 a [ i + 2 ] a[i+2] a[i+2] 构成三角形那么其他的数更没办法满足两边之和大于 a [ i + 2 ] a[i+2] a[i+2] 。但是其复杂度是 O ( n l o g n ) O(nlogn) O(nlogn) 是难以支持 q q q 次查询的
我们继续考虑优化 a [ i ] + a [ i + 1 ] > a [ i + 2 ] a[i]+a[i+1]>a[i+2] a[i]+a[i+1]>a[i+2] ,我们发现当让不等号为等号时有 a [ i ] + a [ i + 1 ] = a [ i + 2 ] a[i]+a[i+1]=a[i+2] a[i]+a[i+1]=a[i+2] 此式子为斐波那契数列的递推式,而我们知道斐波那契数列在第 46 46 46 项的时候就爆 i n t int int 了,题目给出 a [ i ] a[i] a[i] 的范围是 a [ i ] ≤ 1 e 9 a[i]\le 1e9 a[i]1e9 ,因此当 r − l + 1 ≥ 45 r-l+1\ge 45 rl+145 即区间长度大于 45 45 45 时我们可以直接判断其可以找到三个元素使之作为三角形的三边,对于 r − l + 1 < 45 r-l+1< 45 rl+1<45 时用之前那个 n l o g n nlogn nlogn 的方法暴力处理即可,其时间复杂度为 O ( q 45 l o g 45 ) O(q45log45) O(q45log45)

具体细节见代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<set>
#include<map>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int read()
{
	int res = 0,flag = 1;
	char ch = getchar();
	while(ch<'0' || ch>'9')
	{
		if(ch == '-') flag = -1;
		ch = getchar();
	}
	while(ch>='0' && ch<='9')
	{
		res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0';
		ch = getchar();
	}
	return res*flag;
}
const int maxn = 1e5+5;
const int mod = 1e9+7;
const double pi = acos(-1);
const double eps = 1e-8;
int n,q,a[maxn],tmp[maxn];
int main()
{
	n = read();q = read();
	for(int i = 1;i <= n;i++)
		a[i] = read();
	while(q--)
	{
		int l = read(),r = read();
		int len = r-l+1;
		if(len >= 45) 
		{
			puts("clynb");
			continue;
		}
		if(len <= 2) 
		{
			puts("clycdd");
			continue;
		}
		for(int i = 0;i < len;i++)
			tmp[i] = a[l+i];
		sort(tmp,tmp+len);
		bool flag = false;
		for(int i = 2;i < len;i++)
		{
			if(tmp[i-2]+tmp[i-1] > tmp[i])
			{
				flag = true;
				break;
			}
		}
		if(flag) puts("clynb");
		else puts("clycdd");
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值