目录
Description
有 \(n\) 个可重集合,有两种操作
\(Quant\ l \ r\ x\) :在区间 \([l, r]\) 内都加入数 \(x\)
\(Ask\ l\ r\):从 \([l,r]\) 内取出三个数是否可以构成三角形
State
\(1<=n,m<=10^5\)
\(1<=x<=10^9\)
Input
5 5
1 10 2 6 2
Ask 1 3
Quant 1 2 5
Ask 1 3
Quant 1 4 5
Ask 4 5
Output
NO
YES
YES
Solution
一个集合中不可以构成三角形最坏的情况为 \(a+b=c\),也就是全部都是斐波那契数列中的数,这也就决定了一个集合中所拥有数量的上限并不会超过 \(50\)
\(Quant\) :如果这个区间内最小的集合个数大于 \(50\) 就不更新,否则更新
\(Ask\):如果这个区间内所有的数的个数大于 \(50\) 就合法,否则暴力判断
Code
const int N = 1e5 + 5;
int n, m, k, _;
int a[N];
struct Node
{
int l, r;
int sum;
int minn;
#define lson id << 1
#define rson id << 1 | 1
void update(int x)
{
sum += x;
minn += x;
}
}t[N << 2];
vector<int> all[N];
void push_up(int id)
{
t[id].sum = t[lson].sum + t[rson].sum;
t[id].minn = min(t[lson].minn, t[rson].minn);
}
void build(int l, int r, int id)
{
t[id].l = l, t[id].r = r;
if(l == r) t[id].minn = t[id].sum = 1;
else{
int mid = l + r >> 1;
build(l, mid, lson);
build(mid + 1, r, rson);
push_up(id);
}
}
void update(int l, int r, int id, int x)
{
int L = t[id].l, R = t[id].r;
if(L >= l && r >= R && t[id].minn >= 50){
return ;
}
if(L == R){
all[L].pb(x);
t[id].update(1);
}
else{
int mid = L + R >> 1;
if(mid >= l) update(l, r, lson, x);
if(r >= mid + 1) update(l, r, rson, x);
push_up(id);
}
}
int query(int l, int r, int id)
{
int L = t[id].l, R = t[id].r;
if(L >= l && r >= R){
return t[id].sum;
}
else{
int mid = L + R >> 1;
int ans = 0;
if(mid >= l) ans += query(l, r, lson);
if(r >= mid + 1) ans += query(l, r, rson);
return ans;
}
}
signed main()
{
// IOS;
while(~ sdd(n, m)){
rep(i, 1, n) sd(a[i]), all[i].pb(a[i]);
build(1, n, 1);
while(m --> 0){
char opt[5];
int l, r, x;
ss(opt);
sdd(l, r);
if(opt[0] == 'A'){
int ans = query(l, r, 1);
if(ans >= 50) puts("YES");
else{
vector<int> v;
for(int i = l; i <= r; i ++){
for(auto it : all[i]) v.pb(it);
}
int sz = v.size(), ok = 0;
if(sz >= 3){
sort(v.begin(), v.end());
for(int i = 2; i < sz; i ++){
if(v[i - 2] + v[i - 1] > v[i]){
ok = 1;
break;
}
}
}
if(ok) puts("YES");
else puts("NO");
}
}
else if(opt[0] == 'Q'){
sd(x);
update(l, r, 1, x);
}
}
}
// PAUSE;
return 0;
}