这道题ODT复杂度是多少
查看原帖
这道题ODT复杂度是多少
390033
_caiji_楼主2021/4/3 10:59

rt,跑了 27ms,代码:

#include <set>
#include <cstdio>
using namespace std;
template<class T=long long>
class ODT{
    private:
        struct node{
            int l,r;
            mutable T v;
            node(int l,int r=-1,T v=0):l(l),r(r),v(v){}
            inline bool operator<(const node &b)const{return l<b.l;}
            inline friend int rangelen(const node &a){return a.r-a.l+1;}
        };
        std::set<node> s;
        typedef typename std::set<node>::iterator IT;
    public:
        void init(int n){
//            s.insert(node(n+1,n+1));
//            for(int i=1;i<=n;i++) s.insert(node(i,i,a[i]));
            s.insert(node(0,n,0));
        }
        IT split(int pos){
            IT it=s.lower_bound(node(pos));
            if(it!=s.end()&&it->l==pos) return it;
            --it;
            int l=it->l,r=it->r;
            T v=it->v;
            s.erase(it);
            s.insert(node(l,pos-1,v));
            return s.insert(node(pos,r,v)).first;
        }
        void assign(int l,int r,T v=0){
            IT R=split(r+1),L=split(l);
            s.erase(L,R);
            s.insert(node(l,r,v));
        }
        int getans(int l,int r){
            int ans=0; 
            IT R=split(r+1),L=split(l);
            for(IT it=L;it!=R;++it){
                if(it->v==0) ans+=rangelen(*it);
            }
            return ans;
        }
//        template<class function>
//        void work(int l,int r,function work){
//            IT L=split(l),R=split(r+1);
//            for(IT it=L;it!=R;++it) work();
//        }
};
ODT<short int> a;
int n,q,l,r,k;
int main(){
    scanf("%d%d",&n,&q);
    a.init(n);
    for(int i=1;i<=q;i++){
        scanf("%d%d",&l,&r);
        a.assign(l,r,1);
    }
    printf("%d",a.getans(0,n));
    return 0;
}
2021/4/3 10:59
加载中...