【setDS】牛客练习赛90 D
2023-12-20 06:44:06
题意
?
思路
DS题,答案是在 l ~ r 的集合中能否找出3个元素构成三角形
首先有个结论,若元素个数 >= 46,则这堆元素中一定能找出这样的三元组,证明就是斐波那契的极限情况
因此,若询问区间长度 >= 46,则一定能找到,如果不是的话考虑暴力即可
然后对于操作,每次暴力操作肯定不行。我们操作的集合一定是size <= 46的,考虑去维护元素个数 <= 46的集合位置,对于这些位置暴力修改即可
考虑复杂度,如果一个位置的集合的大小 >= 46了会被删除,因此一个位置的复杂度贡献就是 O(46?* logn),一个位置只能被修改一次,修改的总复杂度就是O(46 * n * logn)
#include <bits/stdc++.h>
#define int long long
constexpr int N = 1e5 + 10;
constexpr int M = 1e4 + 10;
constexpr int mod = 1e9 + 7;
std::set<int> S;
std::vector<int> V[N];
int n, m;
int a[N];
void solve() {
std::cin >> n >> m;
for (int i = 1; i <= n; i ++) {
S.insert(i);
std::cin >> a[i];
V[i].push_back(a[i]);
}
while(m --) {
std::string op;
std::cin >> op;
if (op == "Ask") {
int l, r;
std::cin >> l >> r;
if (r - l >= 46) {
std::cout << "YES" << "\n";
continue;
}
std::vector<int> V2;
bool ok = false;
for (int i = l; i <= r; i ++) {
for (auto x : V[i]) {
V2.push_back(x);
}
if (V2.size() >= 46) {
break;
}
}
if (V2.size() >= 46) {
std::cout << "YES" << "\n";
continue;
}
if (V2.size() <= 2) {
std::cout << "NO" << "\n";
continue;
}
std::sort(V2.begin(), V2.end());
for (int i = 2; i < V2.size(); i ++) {
if (V2[i - 2] + V2[i - 1] > V2[i]) {
ok = true;
}
}
if (ok) {
std::cout << "YES" << "\n";
}else {
std::cout << "NO" << "\n";
}
}else {
int l, r, x;
std::cin >> l >> r >> x;
int cur = l - 1;
while(cur <= r) {
std::set<int>::iterator it = S.upper_bound(cur);
if (it == S.end() || *it > r || *it < l) {
break;
}
cur = *it;
V[cur].push_back(x);
if (V[cur].size() >= 46) {
S.erase(cur);
}
}
}
}
}
signed main(){
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t = 1;
while(t --) {
solve();
}
return 0;
}
文章来源:https://blog.csdn.net/weixin_62528401/article/details/135097807
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!