線段樹經典題
線段樹功能: 1.區間覆蓋
2.查詢區間最長連續1個數
程式碼:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define for if(0); else for
const int N=65536+10;
struct SegNode{
int lsum,rsum,csum;
int color;
};
struct SegTree{
SegNode a[N<<2];
int n,Q;
void Init(int n){
this->n=n;
for(Q=1;Q<=n+2;Q<<=1);
memset(a,0,(Q<<1|1)*sizeof(int));
}
void update(int rt,int color,int L){
int val=color==0?0:L;
a[rt].lsum=a[rt].rsum=a[rt].csum=val;
a[rt].color=color;
}
void pushup(int rt,int L){
if(rt>=Q) return;
a[rt].lsum=a[rt<<1].lsum;
a[rt].rsum=a[rt<<1|1].rsum;
if(a[rt].lsum==L>>1) a[rt].lsum+=a[rt<<1|1].lsum;
if(a[rt].rsum==L>>1) a[rt].rsum+=a[rt<<1].rsum;
a[rt].csum=max(max(a[rt<<1].csum,a[rt<<1|1].csum),a[rt<<1].rsum+a[rt<<1|1].lsum);
if(a[rt<<1].color==a[rt<<1|1].color) a[rt].color=a[rt<<1].color;
else a[rt].color=-1;
}
void pushdown(int rt,int L){
if(rt>=Q) return;
if(a[rt].color!=-1){
a[rt<<1].color=a[rt<<1|1].color=a[rt].color;
int val=a[rt].color==0?0:L>>1;
a[rt<<1].lsum=a[rt<<1|1].lsum=val;
a[rt<<1].rsum=a[rt<<1|1].rsum=val;
a[rt<<1].csum=a[rt<<1|1].csum=val;
}
}
void cover(int L,int R,int l,int r,int rt,int color){
if(L<=l && r<=R){
update(rt,color,r-l+1);
return;
}
if(rt>=Q) return;
pushdown(rt,r-l+1);
int m=(l+r)>>1;
if(L<=m) cover(L,R,l,m,rt<<1,color);
if(m<R) cover(L,R,m+1,r,rt<<1|1,color);
pushup(rt,r-l+1);
}
int query(int x,int l,int r,int rt){
if(a[rt].lsum>=x) return l;
pushdown(rt,r-l+1);
if(rt<Q){
int m=(l+r)>>1;
if(a[rt<<1].csum>=x) return query(x,l,m,rt<<1);
else if(a[rt<<1].rsum+a[rt<<1|1].lsum>=x) return m-a[rt<<1].rsum+1;
else if(a[rt<<1|1].csum>=x) return query(x,m+1,r,rt<<1|1);
}
return -1;
}
void cover(int L,int R,int color){
cover(L,R,0,Q-1,1,color);
}
int query(int x){
return query(x,0,Q-1,1);
}
}st;
int n,m;
int main() {
setbuf(stdout,NULL);
while(scanf("%d%d",&n,&m)!=EOF){
st.Init(n);
st.cover(1,n,1);
for(int i=0;i<m;i++){
int op,x1,x2;
scanf("%d",&op);
if(op==1){
scanf("%d",&x1);
int r=st.query(x1);
if(r==-1) printf("0\n");
else printf("%d\n",r),st.cover(r,r+x1-1,0);
}else{
scanf("%d%d",&x1,&x2);
st.cover(x1,x1+x2-1,1);
}
}
}
return 0;
}