题目链接:Codeforces - Physical Education Lessons
做法很多,离散化线段树,动态开点线段树,ODT,Splay。
这四种都是随便维护一下就行了。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=3e5+10,M=N*50;
int n,q,rt=1,sum[M],lc[M],rc[M],lazy[M],cnt=1;
char *fs,*ft,buf[1<<20];
#define gc() (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<20,stdin),fs==ft))?0:*fs++;
inline int read(){
int x=0,f=1; char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f;
}
inline void push_up(int p){sum[p]=sum[lc[p]]+sum[rc[p]];}
inline void push_down(int p,int l,int r){
if(lazy[p]==-1) return ; int mid=l+r>>1;
lazy[lc[p]]=lazy[rc[p]]=lazy[p];
sum[lc[p]]=(mid-l+1)*lazy[p];
sum[rc[p]]=(r-mid)*lazy[p];
lazy[p]=-1;
}
void change(int p,int l,int r,int ql,int qr,int k){
if(l==ql&&r==qr){sum[p]=(r-l+1)*k; lazy[p]=k; return ;}
if(!lc[p]&&!rc[p]) lc[p]=++cnt,lazy[cnt]=-1,rc[p]=++cnt,lazy[cnt]=-1;
int mid=l+r>>1; push_down(p,l,r);
if(qr<=mid) change(lc[p],l,mid,ql,qr,k);
else if(ql>mid) change(rc[p],mid+1,r,ql,qr,k);
else change(lc[p],l,mid,ql,mid,k),change(rc[p],mid+1,r,mid+1,qr,k);
push_up(p);
}
signed main(){
n=read(),q=read(); lazy[1]=-1;
for(int i=1,l,r,k;i<=q;i++){
l=read(),r=read(),k=read(); change(rt,1,n,l,r,(k==1?1:0));
printf("%d\n",n-sum[rt]);
}
return 0;
}