感觉这题还可以,不像以前的模板题一样,貌似教会我一些其他的东西...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;
}
京公网安备 11010502036488号