2021-08-16 SSL 模拟赛 T4
Quantask 大爷,stoorz 大爷,my_dog 大爷 yyds!!!!!
题目大意:
给你一堆集合,每次操作可以往 [ l , r ] [l,r] [l,r] 内的集合加入一个数,或者询问从 [ l , r ] [l,r] [l,r]的所有集合中是否存在三个数可以作为一个三角形的边长。
思路:
我们考虑一个集合内的数怎么样才能无法构成一个三角形。
假设
a
[
1
]
=
1
,
a
[
2
]
=
2
a[1]=1,a[2]=2
a[1]=1,a[2]=2 那么
m
i
n
(
a
[
3
]
)
=
2
min(a[3])=2
min(a[3])=2,继续推,
m
i
n
(
a
[
4
]
)
=
3
min(a[4])=3
min(a[4])=3
然后我们发现
m
i
n
(
a
[
i
]
)
=
a
[
i
−
1
]
+
a
[
i
−
2
]
min(a[i])=a[i-1]+a[i-2]
min(a[i])=a[i−1]+a[i−2],这不就是斐波那契数列吗?
然后看到题目中的
x
<
=
1
0
9
x<=10^9
x<=109,发现在斐波那契数列中第 45 项就已经超过了
1
0
9
10^9
109,所以如果一个集合内数的个数
>
=
45
>=45
>=45 个,那么这个集合一定可以拼出三角形。
然后我们每次加数时如果遇到超过45 个数的集合就跳过,这个过程可以用一个链表或并查集来维护。
然后查询的时候,如果有集合内元素的个数超过 45 个就说明可以,如果没超过 45 个数的一群集合内的元素个数和超过 45 个也可以拼成。然后再把剩下的数排序去判断即可。
时间复杂度大约是
O
(
(
n
+
m
)
∗
45
)
O((n+m)*45)
O((n+m)∗45),最好使用快读快输。
我写的是链表维护,并查集大家可以自行思考。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
const ll V=1e5+10,lim=45;
ll n,m,a[V][lim+5],nxt[V],f[V],top[V],pre[V];
ll x,y,k,tot,b[V];
string s;
ll in()
{
ll res=0,f=1;
char ch;
while((ch=getchar())<'0'||ch>'9')
if(ch=='-') f=-1;
res=res*10+ch-48;
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-48;
return res*f;
}
bool check()
{
if(tot>=lim) return true;
sort(b+1,b+tot+1);
rep(i,3,tot)
if(b[i]<b[i-1]+b[i-2]) return true;
return false;
}
int main()
{
scanf("%lld%lld",&n,&m);
rep(i,1,n)
{
a[i][1]=in();
nxt[i]=i+1;pre[i]=i-1;
++top[i];
}
rep(i,1,m)
{
cin>>s;
if(s=="Quant")
{
x=in(),y=in(),k=in();
for(r ll j=x;j<=y;j=nxt[j])
{
if(top[j]>=lim)
{
pre[nxt[j]]=pre[j];
nxt[pre[j]]=nxt[j];
continue ;
}
a[j][++top[j]]=k;
}
}
else
{
x=in(),y=in();
tot=0;
bool flag=false;
for(r ll j=x;j<=y;j=nxt[j])
{
if(nxt[j]!=j+1||top[j]>=lim)
{
flag=true;
printf("stoorz\n");
break ;
}
rep(k,1,top[j]) b[++tot]=a[j][k];
if(tot>=lim)
{
flag=true;
printf("stoorz\n");
break ;
}
}
if(!flag)
{
if(check()) printf("stoorz\n");
else printf("my_dog\n");
}
}
}
return 0;
}