感觉这题还可以,不像以前的模板题一样,貌似教会我一些其他的东西...2333贴个代码吧~
#include <bits/stdc++.h> using namespace std; const int N=1e5+50; int ans1=0,ans2=0; struct Tree{ int l,r,len,val;//1表示原来那颗大树,0表示没树苗,2表示有树苗,-1表示这个节点不能全部包括. }tr[N<<2]; void cut(int u,int l,int r) { if(tr[u].l>r||tr[u].r<l) return; if(tr[u].val!=-1) tr[u<<1].val=tr[u<<1|1].val=tr[u].val; if(l<=tr[u].l&&tr[u].r<=r&&tr[u].val!=-1) { if(tr[u].val==1) tr[u].val=0; if(tr[u].val==2) { ans1-=tr[u].len; ans2+=tr[u].len; tr[u].val=0; } return; } cut(u<<1,l,r); cut(u<<1|1,l,r); if(tr[u<<1].val!=tr[u<<1|1].val) tr[u].val=-1; else tr[u].val=tr[u<<1].val; } void plant(int u,int l,int r) { if(tr[u].l>r||tr[u].r<l) return; if(tr[u].val!=-1) tr[u<<1].val=tr[u<<1|1].val=tr[u].val; if(l<=tr[u].l&&tr[u].r<=r&&tr[u].val!=-1) { if(tr[u].val==0) ans1+=tr[u].len,tr[u].val=2; return; } plant(u<<1,l,r); plant(u<<1|1,l,r); if(tr[u<<1].val!=tr[u<<1|1].val) tr[u].val=-1; else tr[u].val=tr[u<<1].val; } void build(int u,int l,int r) { tr[u].l=l,tr[u].r=r,tr[u].val=1,tr[u].len=(r-l+1); if(l==r) return; int mid=(l+r)>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); } int main() { int n,m; scanf("%d%d",&n,&m);n++; build(1,1,n); for(int i=1;i<=m;i++) { int a,b,c;scanf("%d%d%d",&a,&b,&c); b++,c++; if(a==0) cut(1,b,c); else plant(1,b,c); }printf("%d\n%d\n",ans1,ans2);//校门外留下的树苗数目 种上又被拔掉的树苗数目 return 0; }