首页 > 其他分享 >CF1991F Triangle Formation 题解

CF1991F Triangle Formation 题解

时间:2024-09-07 16:36:37浏览次数:5  
标签:CF1991F return int 题解 Formation vec && 三角形 check

Description

你有 \(n\) 根棍子,从 \(1\) 到 \(n\) 编号。第 \(i\) 根棍子的长度是 \(a_i\)。

你需要回答 \(q\) 个问题。在每个查询中,你会得到两个整数 \(l\) 和 \(r\)(\(1 \le l < r \le n,r − l + 1 \ge 6\))。确定是否可以从编号为 \(l\) 到 \(r\) 的棒中选择 \(6\) 个不同的棒,形成 \(2\) 个非退化三角形。

边长为 \(a\)、\(b\) 和 \(c\) 的三角形称为非退化三角形,当且仅当 \(a<b+c,b<a+c,c<a+b\)。

Solution

先考虑什么样的序列存在至少一个三角形。容易发现把序列排序后,如果存在三角形,则必存在一个长度为 \(3\) 的连续区间满足条件。

而如果不存在,则一定满足 \(a_i\geq a_{i-1}+a_{i-2}\)。经过计算,这样的序列长度一定不超过 \(45\),即长度不小于 \(45\) 的序列一定存在至少一个三角形。

回到这个题。利用上面那个结论可以得出序列长度 \(\geq 48\) 时一定存在答案,因为这里至少存在一个三角形,去掉这个三角形后还剩 \(45\) 个数,所以存在第二个。

于是 \(r-l+1\geq 48\) 时必然有解,现在需要判断 \(r-l+1\leq 47\) 时是否有解。

同样是先排序,把所有形如 \((i,i+1,i+2)\) 且满足 \(a_i+a_{i+1}>a_{i+2}\) 的数对拿出来,如果存在两个数对不相交则一定有解。

如果不存在则说明最终的两个三角形是相交的,就像 \((1,2,4),(3,5,6)\) 这种。注意到这时选的 \(6\) 个数如果不是连续的 \(6\) 个则调整成连续的一定更优,所以只需要对于所有连续的 \(6\) 个数暴力判断即可。

时间复杂度:\(O(n\log V\log\log V)\)。

Code

#include <bits/stdc++.h>

// #define int int64_t

const int kMaxN = 1e5 + 5;

int n, q;
int a[kMaxN];

bool check(int64_t x, int64_t y, int64_t z) {
  return x + y > z && x + z > y && y + z > x;
}

bool check(int l, int r) {
  std::vector<int> vec;
  for (int i = l; i <= r; ++i) vec.emplace_back(a[i]);
  std::sort(vec.begin(), vec.end());
  int mi = 1e9;
  for (int i = 2; i < (int)vec.size(); ++i) {
    if (check(vec[i - 2], vec[i - 1], vec[i])) {
      if (i - 2 > mi) return 1;
      if (mi == 1e9) mi = i;
    }
  }
  for (int i = 0; i + 5 < (int)vec.size(); ++i) {
    if (check(vec[i], vec[i + 1], vec[i + 2]) && check(vec[i + 3], vec[i + 4], vec[i + 5])) return 1;
    if (check(vec[i], vec[i + 1], vec[i + 3]) && check(vec[i + 2], vec[i + 4], vec[i + 5])) return 1;
    if (check(vec[i], vec[i + 1], vec[i + 4]) && check(vec[i + 2], vec[i + 3], vec[i + 5])) return 1;
    if (check(vec[i], vec[i + 1], vec[i + 5]) && check(vec[i + 2], vec[i + 3], vec[i + 4])) return 1;
    if (check(vec[i], vec[i + 2], vec[i + 3]) && check(vec[i + 1], vec[i + 4], vec[i + 5])) return 1;
    if (check(vec[i], vec[i + 2], vec[i + 4]) && check(vec[i + 1], vec[i + 3], vec[i + 5])) return 1;
    if (check(vec[i], vec[i + 2], vec[i + 5]) && check(vec[i + 1], vec[i + 3], vec[i + 4])) return 1;
    if (check(vec[i], vec[i + 3], vec[i + 4]) && check(vec[i + 1], vec[i + 2], vec[i + 5])) return 1;
    if (check(vec[i], vec[i + 3], vec[i + 5]) && check(vec[i + 1], vec[i + 2], vec[i + 4])) return 1;
    if (check(vec[i], vec[i + 4], vec[i + 5]) && check(vec[i + 1], vec[i + 2], vec[i + 3])) return 1;
  }
  return 0;
}

void dickdreamer() {
  std::cin >> n >> q;
  for (int i = 1; i <= n; ++i) std::cin >> a[i];
  for (int i = 1; i <= q; ++i) {
    int l, r;
    std::cin >> l >> r;
    if (r - l + 1 >= 48) std::cout << "YES\n";
    else std::cout << (check(l, r) ? "YES\n" : "NO\n");
  }
}

int32_t main() {
#ifdef ORZXKR
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
#endif
  std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
  int T = 1;
  // std::cin >> T;
  while (T--) dickdreamer();
  // std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
  return 0;
}

标签:CF1991F,return,int,题解,Formation,vec,&&,三角形,check
From: https://www.cnblogs.com/Scarab/p/18401852

相关文章

  • [ABC293Ex] Optimal Path Decomposition 题解
    [ABC293Ex]OptimalPathDecomposition题解是一道难得一遇的好题。对于题目中的两个限制,同时满足是困难的,于是考虑常见的套路:先固定其中一个,再计算另一个。对于本题,显然\(k\)是有单调性的,于是考虑二分这个\(k\),将最优性问题转化为可行性问题,dp路径的最小长度。那么考虑d......
  • CF1991E Coloring Game 题解
    Description有一个由\(n\)个顶点和\(m\)条边组成的无向图。每个顶点可以用三种颜色之一着色:\(1\)、\(2\)或\(3\)。初始时,所有顶点都未着色。Alice和Bob正在玩一个包含\(n\)轮的游戏。在每一轮中,都会发生以下两个步骤:Alice选择两种不同的颜色。Bob选择一个未......
  • CF2009G. Yunli's Subarray Queries 题解
    G1题目要求,对于一个子区间$a_{l\siml+k-1}$,最少要进行多少次单点修改,才能使$\forall\l<i\leql+k-1,a_i=a_{i-1}+1$,其中$k$是固定的。对于这种问题,我们通常有一个trick:将$a_i$变为$a_i-i$。这样的话,我们要求的答案就变为了$k$减去变化后的$a_{l\siml+k-1}$......
  • RecyclerView 高效使用与常见问题解决
    RecyclerView是Android应用开发中最常用的UI组件之一,通常用于显示大量数据列表。尽管功能强大,但如果使用不当,会导致性能问题、数据错乱或滚动卡顿等问题。在本篇文章中,我们将探讨RecyclerView的一些常见坑点,提供解决方案,并附带代码示例。1.坑点:ViewHolder重用导致数据错乱......
  • ctfshow web红包题第二弹题解
    从今天开始记录刷题日常打开靶场平平无奇,看源代码发现如下提示get方式提交cmd参数,猜测是命令执行漏洞,先写个phpinfo();试试。有用,但报错cerror查看显示出来部分php代码,过滤了很多东西if(preg_match("/[A-Za-oq-z0-9$]+/",$cmd)) 第一个正则表达式把字母数字几乎全......
  • [ABC137F] Polynomial Construction 题解
    明明有最厉害最好想的插值做法,怎么没有人写呢。思路考虑\(n\)个点可以确定一个\(n-1\)次多项式。如何确定。令\(l_i(x)=\prod_{j\not=i}\frac{(x-x_j)}{(x_i-x_j)}\)。可以发现这个多项式在\(x=x_i\)时值为一,在\(x=x_j(j\not=i)\)时值为零。那么就有:\[F(x)=\su......
  • 洛谷 P3034 Cow Photography G/S——题解
    洛谷P3034题解传送锚点摸鱼环节[USACO11DEC]CowPhotographyG/S题面翻译题目描述今天的奶牛们特别调皮!FarmerJohn想做的只是给排成一排的奶牛拍照,但是在他拍下照片之前,奶牛们一直在移动。具体地说,FJ有\(N\)头奶牛(\(1\leqN\leq20\,000\)),每头奶牛都有一个唯一确......
  • 题解:AT_abc369_e [ABC369E] Sightseeing Tour 详细版
    题目大意给定一个NNN个点,MMM条边的无向图。其中边有边权。有......
  • MySQL 日期函数语法介绍和案例示范以及常见问题解决
    本文将以电商交易系统为例,详细讲解MySQL日期类型及其转化,常用的日期函数,以及一些解决常见问题的方案。一、MySQL日期数据类型MySQL提供了多种日期数据类型,适用于不同的使用场景。常见的日期类型包括DATE、DATETIME、TIMESTAMP、TIME和YEAR。DATE:只存储日期,不包含......
  • 题解:SP3693 KGSS - Maximum Sum
    原题传送门思路分析线段树。这道题让我们进行两种操作,分别是单点修改和区间查询,结合数据范围,很明显是一道线段树。区间里最大的\(A_i+A_j\),其实就是求区间里的最大值和次大值,我们用线段树维护最大值和次大值。建树voidbuild(intnow,inttl,inttr){ if(tl==tr){ tmax......