妄想集合(牛客练习赛90)
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了妄想集合(牛客练习赛90)相关的知识,希望对你有一定的参考价值。
题意:
开始有 n 个可重集合,开始时每一个集合中都有一个数,有 m 个操作。
Quant l r x
\\text{Quant l r x}
Quant l r x:往编号在
l
∼
r
l\\sim r
l∼r 的每个集合中加入一个数 x。
Ask l r
\\text{Ask l r}
Ask l r:询问能否从
l
∼
r
l\\sim r
l∼r的集合中取出三个数使得他们能作为边长组成一个三角形(即最小两个和要大于最大的)。
1<=n,m<=1e5
所有数<=1e9
题解:
一开始在想如何快速判断边长能否组成三角形,陷入了死胡同里,后来在队友一说才想起来,不能组成三角形的情况就是斐波那契而数列。
以前有遇到过,一个最大的集合无法组成三角形,那么这个集合中的元素为1,1,2,3,5,6…就是斐波那契数列,而都知道这个数列增长是否快的,到1e9以内最多也才40多个,也就是说如果一个区间内元素个数大于上限(我们将上限lim定为60)直接就是Yes,修改时也只需要修改元素个数小于lim的集合即可
判断的时候,只要集合内元素大于lim就是Yes,如果小于,我们就直接硬判断即可,因为一共才不到60个数
复杂度:
O
(
n
∗
l
o
g
n
∗
60
)
O(n*logn*60)
O(n∗logn∗60)
代码:
#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\\n", a, b);
#define Memory() printf("%.2lfMB\\n",(&Most-&Handsome)/1024.0/1024.0);
using namespace std;
bool Handsome;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{
x= 0;
char c= getchar();
bool flag= 0;
while (c < '0' || c > '9')
flag|= (c == '-'), c= getchar();
while (c >= '0' && c <= '9')
x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();
if (flag)
x= -x;
read(Ar...);
}
template <typename T> inline void write(T x)
{
if (x < 0) {
x= ~(x - 1);
putchar('-');
}
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
void rd_test()
{
#ifdef ONLINE_JUDGE
#else
startTime = clock ();
freopen("data.in", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#else
endTime= clock();
printf("\\nRun Time:%lfs\\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
int n,m;
const int maxn=1e5+9;
vector<int>vec[maxn];
set<int>pos;
bool Most;
int main()
{
//rd_test();
cin>>n>>m;
for(int i=1;i<=n;i++){
int x;
cin>>x;
vec[i].push_back(x);//每个集合
pos.insert(i);
}
while(m--){
string op;
int l,r;
cin>>op>>l>>r;
if(op=="Quant"){
int x;
cin>>x;
set<int>::iterator it=pos.lower_bound(l);
while(it!=pos.end()&&*it<=r){//对集合进行维护
vec[(*it)].push_back(x);
if(vec[*it].size()>60)
pos.erase(it++);
else
it++;
}
}
else {
if(r-l+1>60){
puts("YES");
continue;
}
vector<int>tmp;
for(int i=l;i<=r;i++)
tmp.insert(tmp.end(),vec[i].begin(),vec[i].end());
sort(tmp.begin(),tmp.end());
bool flag=0;
for(int i=1;i<tmp.size()-1;i++){
if(tmp[i-1]+tmp[i]>tmp[i+1]){
puts("YES");
flag=1;
break;
}
}
if(!flag)
puts("NO");
}
}
return 0;
//Time_test();
}
以上是关于妄想集合(牛客练习赛90)的主要内容,如果未能解决你的问题,请参考以下文章