将用的点存起来。中间没用过的点连续的一组压缩成一个点,将这些点离散化处理。
线段树区间修改
#include<bits/stdc++.h> #define ll long long #define ls (p<<1) #define rs ((p<<1)|1) #define mid ((t[p].l+t[p].r)>>1) #define pb push_back #define pii pair<int,int> #define mk make_pair #define fi first #define se second using namespace std; int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } return x*f; } inline void Prin(int x){ //__int128x if(x < 0){ putchar('-'); x = -x; } if(x > 9) Prin(x / 10); putchar(x % 10 + '0'); } const int qs=2e6+7; struct Tree{ int l,r,val,add; #define l(x) t[x].l #define r(x) t[x].r #define val(x) t[x].val #define add(x) t[x].add }t[qs<<2]; int n,f[qs],a[qs],cnt,u[qs],q; void build(int p,int l,int r){ l(p)=l,r(p)=r; add(p)=-1; if(l==r) { val(p)=f[l]; return; } build(ls,l,mid); build(rs,mid+1,r); val(p)=val(ls)+val(rs); } int cal(int p){ return f[r(p)]-f[l(p)-1]; } void down(int p){ if(add(p)==-1) return; val(ls)=cal(ls)*add(p); val(rs)=cal(rs)*add(p); add(ls)=add(p); add(rs)=add(p); add(p)=-1; } void update(int p,int l,int r,int k){ if(l<=l(p)&&r>=r(p)){ val(p)=cal(p)*k; add(p)=k; return; } down(p); if(l<=mid) update(ls,l,r,k); if(r>mid) update(rs,l,r,k); val(p)=val(ls)+val(rs); } struct node{ int id,val,k; bool operator < (const node &tem) const{ return val<tem.val; } }A[qs]; int main(){ n=read(); q=read(); for(int i=1;i<=q*2;i+=2) { A[i].val=read(); A[i+1].val=read(); u[i]=u[i+1]=read()-1; A[i].id=i; A[i+1].id=i+1; } sort(A+1,A+1+q*2); cnt=0; for(int i=1;i<=q*2;++i){ if(A[i].val-A[i-1].val>1){ f[++cnt]=A[i].val-A[i-1].val-1; } if(A[i].val-A[i-1].val==0) { a[A[i].id]=cnt; continue; } f[++cnt]=1; a[A[i].id]=cnt; } if(n-A[q*2].val>=1) f[++cnt]=n-A[q*2].val; build(1,1,cnt); for(int i=1;i<=cnt;++i) f[i]+=f[i-1]; for(int i=1;i<=q*2;i+=2){ update(1,a[i],a[i+1],u[i]); Prin(val(1)); puts(""); } return 0; }