额,今天写一遍校门外的树线段树写法,纯属无聊。
乱写的,根本没有任何优化,速度还满了一点点。
也就是直接从模板上修改的,没有点统计,所以说,看看就好,知道线段树这中鬼东东就好。
额
我用的都是位运算,如果有不知道的,问一下度娘就好了。
额
废话不多说,直接上代码:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
struct node{
int l,r,v;
}a[100010];
void bulid(int k,int l,int r){//建造这样的一棵线段树
a[k].l=l;a[k].r=r;
if(l==r)
return;
int mid=(l+r)>>1;
bulid(k<<1,l,mid);
bulid(k<<1|1,mid+1,r);
}
void insert(int k,int x){//插入一个节点
int l=a[k].l,r=a[k].r;
if(l==r){
a[k].v=1;
return;
}
int mid=(l+r)>>1;
if(x<=mid)
insert(k<<1,x);
else
insert(k<<1|1,x);
a[k].v=a[k<<1|1].v+a[k<<1].v;
}
int find(int k,int x){//查找是否存在这样一个节点
int l=a[k].l,r=a[k].r;
if(l==r){
if(a[k].v)
return 1;
return 0;
}
int mid=(l+r)>>1;
if(x<=mid)
find(k<<1,x);
else
find(k<<1|1,x);
}
int main(){
int n,m,j,k,i,x,y,ans=0;
scanf("%d%d",&n,&m);
bulid(1,0,n);
for(i=1;i<=m;i++){
scanf("%d%d",&x,&y);
for(j=x;j<=y;j++)
if(!find(1,j))
insert(1,j);
}
for(i=0;i<=n;i++)
if(!find(1,i))
ans++;
cout<<ans<<endl;
return 0;
}
额,就是这样,不懂的就~~~争取自己理解吧。
还有,我的线段树速度很慢,是乱写的,不要提交,肯定会WA的啊。
就这样吧,只是告诉童鞋们可以用线段树罢了。