Codeforces Round #773 E

Anonymity Is Important

我们最开始会想到用三个状态表示 其实并不用我们只需要用 0表示这个人没病 1表示不确定有病(这样我们就可以用set来做了)
要是一个区间给了有病 我们只有把其他的所有人都排除成没病才行
比如我们 110000010000111 这个中间的1不一定是一定有病的 他必须被一个区间包括 并且有且仅有他一个1
这里我们可以想到线段树对于每个赋值 让左端点等于r即可(初始化为inf) 然后我们check 该点左边第一个1到该点 区间最小值是否小于该点右边第一个1的下标即可
这里只用了单点修改 区间赋值 所以只用pushup的线段树即可 我们每个点最多修改成一次 0 每个查询最多修改一次 O(nlogn)
注意这里set要多插俩个 不然会越界

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int M = 998244353;
const int mod = 998244353;
#define int long long
#define endl '\n'
#define Endl '\n'
#define YES cout<<"YES"<<endl;
#define NO cout<<"NO"<<endl;
#define _ 0
#define inf 0x3f3f3f3f3f3f3f3f
#define fast ios::sync_with_stdio(false);cin.tie(nullptr);
struct node{
    int l,r,sum;
}tree[N<<2];
void pushup(node &u,node &l,node &r){
    u.sum=min(l.sum,r.sum);
}
inline void pushup(int u){
    pushup(tree[u],tree[u<<1],tree[u<<1|1]);
}
inline void build(int i,int l,int r){
    tree[i].l=l;tree[i].r=r;
    if(l==r){
        tree[i].sum=inf; //按要求赋值
        return ;
    }
    int mid=l+r>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    pushup(i);
}
inline void modify(int i,int dis,int k){
    if(tree[i].l==tree[i].r){
        tree[i].sum=min(tree[i].sum,k);//按要求 单点修改
        return ;
    }
    if(dis<=tree[i<<1].r)modify(i<<1,dis,k);
    else modify(i<<1|1,dis,k);
    pushup(i);
}

inline node query(int i,int l,int r){
    //if(l>r)return{0};
    node s;
    if(tree[i].l>=l && tree[i].r<=r)return tree[i];
    else if (tree[i*2].r>=r)  s= query(i<<1,l,r);
    else if(tree[i*2+1].l<=l) s= query(i<<1|1,l,r);
    else{
        auto left = query(i<<1,l,r);
        auto right= query(i<<1|1,l,r);
        node res;
        pushup(res,left,right);
        return res;
    }
    return s;
}
void solve() {
    int n,m;cin>>n>>m;
    set<int>s;
    for(int i=0;i<=n+1;i++)s.insert(i);
    build(1,1,n);
    while(m--){
        int op;cin>>op;
        if(!op){
            int l,r,x;cin>>l>>r>>x;
            if(x){
                modify(1,l,r);
            }else{
                while(s.size()){
                    auto i=s.lower_bound(l);
                    if(*i>r)break;
                    else s.erase(i);
                }
            }
        }else{
            int x;cin>>x;
            if(s.count(x)==0)cout<<"NO"<<endl;
            else {
                auto i=s.lower_bound(x),j=s.upper_bound(x);
                i--;
                if(query(1,*i+1,x).sum<*j)cout<<"YES"<<endl;
                else cout<<"N/A"<<endl;
            }
        }
    }
}
signed main(){
    fast
    int T;T=1;
    while(T--) {
        solve();
    }
    return ~~(0^_^0);
}
posted @ 2022-09-01 19:58  ycllz  阅读(27)  评论(0)    收藏  举报