洛谷P2082 区间覆盖(加强版)(珂朵莉树)
虽然是黄题而且还是一波离散就能解决的东西
然而珂朵莉树还是很好用
相当于一开始区间全为0,然后每一次区间赋值,问最后总权值
珂朵莉树搞一搞就好了
1 //minamoto 2 #include<set> 3 #include<iostream> 4 #include<cstdio> 5 #define ll long long 6 #define IT set<node>::iterator 7 using std::set; 8 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 9 char buf[1<<21],*p1=buf,*p2=buf; 10 ll read(){ 11 #define num ch-'0' 12 char ch;bool flag=0;ll res; 13 while(!isdigit(ch=getc())) 14 (ch=='-')&&(flag=true); 15 for(res=num;isdigit(ch=getc());res=res*10+num); 16 (flag)&&(res=-res); 17 #undef num 18 return res; 19 } 20 struct node{ 21 ll l,r;mutable int v; 22 node(ll L,ll R=-1,int V=0):l(L),r(R),v(V){} 23 inline bool operator <(const node &b)const 24 {return l<b.l;} 25 };set<node> s; 26 IT split(ll pos){ 27 IT it=s.lower_bound(node(pos)); 28 if(it!=s.end()&&it->l==pos) return it; 29 --it;int l=it->l,r=it->r;ll v=it->v; 30 s.erase(it),s.insert(node(l,pos-1,v)); 31 return s.insert(node(pos,r,v)).first; 32 } 33 void assign(ll l,ll r){ 34 IT itr=split(r+1),itl=split(l); 35 s.erase(itl,itr),s.insert(node(l,r,1)); 36 } 37 ll sum(ll l,ll r){ 38 IT itr=split(r+1),itl=split(l);ll res=0; 39 for(;itl!=itr;++itl) res+=itl->v?itl->r-itl->l+1:0; 40 return res; 41 } 42 int main(){ 43 // freopen("testdata.in","r",stdin); 44 int n=read();s.insert(node(0,1e17+5,0)); 45 while(n--){ 46 ll l=read(),r=read();assign(l,r); 47 } 48 printf("%lld\n",sum(0,1e17)); 49 return 0; 50 }
深深地明白自己的弱小