제출 #1324772

#제출 시각아이디문제언어결과실행 시간메모리
1324772okaragulRadio (COCI22_radio)C++20
110 / 110
519 ms50692 KiB
#include <bits/stdc++.h>
using namespace std;

#define ll long long

int minn(int x, int y){
    return min(x, y);
}

struct SegmentTree{
    int N;
    vector<int> arr, st;
    int (*merge)(int, int);

    SegmentTree(int (*f)(int, int), vector<int> arr): N(arr.size()), arr(arr), st(N*4), merge(f){
        build(1, 0, N-1);
    }
    SegmentTree(int (*f)(int, int), int N, int val=0): N(N), arr(N, val), st(N*4), merge(f){
        build(1, 0, N-1);
    }

private:
    int build(int n, int s, int e){
        if(s==e) return st[n]=arr[s];
        int mid=(s+e)/2;
        return st[n]=merge(build(n*2, s, mid), build(n*2+1, mid+1, e));
    }

    void update(int n, int s, int e, int t, int val){
        if(s==e){
            st[n]=val;
            return;
        }

        int mid=(s+e)/2;
        if(mid>=t) update(n*2, s, mid, t, val);
        if(mid<t) update(n*2+1, mid+1, e, t, val);
        st[n]=merge(st[n*2], st[n*2+1]);
    }

    int query(int n, int s, int e, int l, int r){
        if(s>=l && e<=r) return st[n];

        int mid=(s+e)/2;
        if(mid>=l && mid<r) 
            return merge(query(n*2, s, mid, l, r), query(n*2+1, mid+1, e, l, r));
        else if(mid>=l) 
            return query(n*2, s, mid, l, r);
        else 
            return query(n*2+1, mid+1, e, l, r);
    }

public:
    void update(int t, int val){
        update(1, 0, N-1, t, val);
    }

    int query(int l, int r){
        if(r<l) return 0; 
        return query(1, 0, N-1, l, r);
    }
};

int main(){
    int n, q;
    cin>>n>>q;

    vector<int> sieve(n+1);
    iota(sieve.begin(), sieve.end(), 0);
    for(int i=2; i<=n; i++){
        if(sieve[i]!=i) continue;

        for(int j=2*i; j<=n; j+=i)
            sieve[j]=min(sieve[j], i);
    }

    SegmentTree st(minn, n+1, n+1);
    unordered_map<int, set<int>> s;
    vector<int> cnt(n+1);
    while(q--){
        char c;
        cin>>c;

        if(c=='S'){
            int x;
            cin>>x;

            if(!cnt[x]){
                cnt[x]=1;
                int tmp=x, ans=n+1; 
                while(tmp!=1){
                    int p=sieve[tmp];
                    while(tmp%p==0) tmp/=p; 
                    s[p].insert(x);

                    auto nxt=s[p].upper_bound(x);
                    if(nxt!=s[p].end())
                        ans=min(ans, *nxt);

                    auto last=s[p].lower_bound(x);
                    if(last==s[p].begin()) continue;
                    last=prev(last); 
                    if(x<st.query(*last, *last))
                        st.update(*last, x);
                }
                st.update(x, ans);
            }
            else{
                cnt[x]=0;
                int tmp=x; 
                while(tmp!=1){
                    int p=sieve[tmp];
                    while(tmp%p==0) tmp/=p; 
                    s[p].erase(x);

                    auto last=s[p].lower_bound(x);
                    if(last==s[p].begin()) continue;
                    last=prev(last);
                    
                    if(x!=st.query(*last, *last)) continue; 
                    int tmp2=*last, ans=n+1;
                    while(tmp2!=1){
                        int p2=sieve[tmp2];
                        while(tmp2%p2==0) tmp2/=p2;

                        auto next=s[p2].upper_bound(*last);
                        if(next!=s[p2].end())
                            ans=min(ans, *next);
                    }

                    st.update(*last, ans);
                }
                st.update(x, n+1);
            }
        }

        else{
            int l, r;
            cin>>l>>r;

            cout<<(st.query(l, r)<=r ? "DA":"NE")<<'\n';
        }
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...