CF915E Physical Education Lessons(珂朵莉树)
据说正解是动态开点线段树而且标记也不难下传的样子
然而这种区间推平的题目还是喜欢写珂朵莉树啊……码量小……
虽然真要构造的话随便卡……
1 //minamoto 2 #include<cstdio> 3 #include<set> 4 #include<iostream> 5 #define IT set<node>::iterator 6 using namespace std; 7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 8 char buf[1<<21],*p1=buf,*p2=buf; 9 inline int read(){ 10 #define num ch-'0' 11 char ch;bool flag=0;int res; 12 while(!isdigit(ch=getc())) 13 (ch=='-')&&(flag=true); 14 for(res=num;isdigit(ch=getc());res=res*10+num); 15 (flag)&&(res=-res); 16 #undef num 17 return res; 18 } 19 char sr[1<<21],z[20];int K=-1,Z; 20 inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;} 21 inline void print(int x){ 22 if(K>1<<20)Ot();if(x<0)sr[++K]=45,x=-x; 23 while(z[++Z]=x%10+48,x/=10); 24 while(sr[++K]=z[Z],--Z);sr[++K]='\n'; 25 } 26 struct node{ 27 int l,r;mutable int v; 28 node(int L,int R=-1,int V=0):l(L),r(R),v(V){} 29 inline bool operator <(const node &b)const 30 {return l<b.l;} 31 }; 32 set<node> s;int sum; 33 IT split(int pos){ 34 IT it=s.lower_bound(node(pos)); 35 if(it!=s.end()&&it->l==pos) return it; 36 --it; 37 int l=it->l,r=it->r,v=it->v; 38 s.erase(it); 39 s.insert(node(l,pos-1,v?pos-l:0)); 40 return s.insert(node(pos,r,v?r-pos+1:0)).first; 41 } 42 void assign(int l,int r,int v){ 43 IT itr=split(r+1),itl=split(l); 44 for(IT it=itl;it!=itr;++it) sum-=it->v; 45 s.erase(itl,itr),s.insert(node(l,r,v*(r-l+1))); 46 sum+=v*(r-l+1); 47 } 48 int main(){ 49 // freopen("testdata.in","r",stdin); 50 int n=read(),q=read(); 51 s.insert(node(1,n+1,1));sum=n; 52 while(q--){ 53 int l=read(),r=read(); 54 assign(l,r,read()-1); 55 print(sum); 56 } 57 return Ot(),0; 58 }
深深地明白自己的弱小