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

 

posted @ 2018-10-18 16:17  bztMinamoto  阅读(215)  评论(0编辑  收藏  举报
Live2D