2023大厂真题提交网址(含题解):
www.CodeFun2000.com(http://101.43.147.120/)
最近我们一直在将收集到的机试真题制作数据并搬运到自己的OJ上,供大家免费练习,体会真题难度。现在OJ已录入50+道2023年最新大厂真题,同时在不断的更新。同时,可以关注"塔子哥学算法"公众号获得每道题的题解。
题目大意:
https://ac.nowcoder.com/acm/contest/13276/K
very clear
题目思路:
1.化解问题:
给你
n
n
n个数
a
i
≤
1
e
5
a_i \leq 1e5
ai≤1e5.是否能够从里面选出三个数使得构成三角形.
2.结论:
当
n
>
25
n > 25
n>25时,答案一定存在。
要选出三角形,一定是相邻的三个数可能性最大。那么要求一个都不存在。那么就是对于任意一项要满足 a [ i ] > a [ i − 1 ] + a [ i − 2 ] a[i] > a[i-1]+a[i-2] a[i]>a[i−1]+a[i−2].那么这样的数列的递增至少是斐波那契数列。所以当 n > 25 n > 25 n>25时,根据鸽巢原理答案一定存在。
3.有了这个结论。我们就可以直接暴力做了。线段树每个节点维护两个vector.暴力合并。当 s z > 25 sz>25 sz>25。则只加 s z sz sz.无需再暴力合并vector.
然后查询就分情况即可。具体细节看代码。
#include<bits/stdc++.h>
using namespace std;
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define vll vector<ll>
#define fi first
#define se second
#define ll long long
#define tl (t<<1)
#define tr (t<<1|1)
#define mid ((r + l) >> 1)
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
const ll inf = 1e18;
const int mx = 25;
int lazy[maxn<<2] , c[maxn] , b[maxn];
vi a[maxn<<2][2];
int sz[maxn<<2][2];
void pushup(int t)
{
for (int i = 0 ; i <= 1 ; i++){
if (sz[tl][i] + sz[tr][i] <= mx){
a[t][i] = a[tl][i];
for (auto g : a[tr][i]) a[t][i].pb(g);
}
sz[t][i] = sz[tl][i] + sz[tr][i];
}
}
void D(int t)
{
swap(sz[t][0] , sz[t][1]);
swap(a[t][0] , a[t][1]);
lazy[t] ^= 1;
}
void pushdown(int l,int r,int t)
{
if(lazy[t])
{
D(tl);
D(tr);
lazy[t] = 0;
}
}
void Build(int l,int r,int t)
{
lazy[t] = 0;
if(l == r)
{
int g = b[l];
sz[t][g] = 1;
sz[t][!g] = 0;
a[t][g].pb(c[l]);
return ;
}
Build(l , mid , tl);
Build(mid + 1 , r , tr);
pushup(t);
}
void Update(int L,int R,int l,int r,int t)
{
if(L <= l && r <= R){
D(t);
return ;
}
pushdown(l,r,t);
if(L <= mid)
Update(L,R,l,mid,tl);
if(R > mid)
Update(L,R,mid+1,r,tr);
pushup(t);
}
struct Node
{
int sz;
vi a;
void mer (Node f)
{
if (sz + f.sz <= mx)
for (auto g : f.a) a.pb(g);
sz += f.sz;
}
};
Node Query(int L,int R,int l,int r,int t)
{
if(L <= l && r <= R){
Node res;
res.a = a[t][1];
res.sz = sz[t][1];
return res;
}
pushdown(l,r,t);
Node ans = {0 , vi()};
if(L <= mid){
Node res = Query(L,R,l,mid,tl);
ans.mer(res);
}
if(R > mid){
Node res = Query(L,R,mid+1,r,tr);
ans.mer(res);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
int n , m ; cin >> n >> m;
for (int i = 1 ; i <= n ; i++){
cin >> c[i];
}
for (int i = 1 ; i <= n ; i++){
cin >> b[i];
}
Build(1 , n , 1);
for (int i = 1 ; i <= m ; i++){
int op , l , r; cin >> op >> l >> r;
if (op == 1){
Update(l , r , 1 , n , 1);
}else {
Node res = Query(l , r , 1 , n , 1);
if (res.sz > mx) cout << "YES" << endl;
else {
sort(res.a.begin() , res.a.end());
int n = res.a.size();
bool ok = false;
for (int i = 2 ; i < n ; i++){
if (res.a[i - 2] + res.a[i - 1] > res.a[i]) ok = true;
}
if (ok) cout << "YES" << endl;
else cout << "NO" << endl;
}
}
}
return 0;
}