1. 程式人生 > >洛谷P2082 區間覆蓋(加強版)(珂朵莉樹)

洛谷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 }