1. 程式人生 > 其它 >NC11180 D.妄想集合(線段樹)

NC11180 D.妄想集合(線段樹)

目錄

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;
}