poj3667
hdu2871
hdu4614
poj1631 线段树求LIS 单点
poj3667
#include<stdio.h>
#include<iostream>
using namespace std;
#define maxn 111111
int mmax[maxn<<2],lmax[maxn<<2],rmax[maxn<<2];
int set[maxn<<2];
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define mid ((l+r)>>1)
void pushup(int rt,int l,int r)
{
lmax[rt]=lmax[ls];
rmax[rt]=rmax[rs];
if(lmax[ls]==(mid-l+1))lmax[rt]+=lmax[rs];
if(rmax[rs]==(r-mid))rmax[rt]+=rmax[ls];
mmax[rt]=max(mmax[ls],mmax[rs]);
mmax[rt]=max(lmax[rs]+rmax[ls],mmax[rt]);
}
void pushdown(int rt,int l,int r)
{
if(set[rt]!=-1)
{
set[ls]=set[rs]=set[rt];
set[rt]=-1;
lmax[ls]=mmax[ls]=rmax[ls]=(set[ls]?0:(mid-l+1));
lmax[rs]=mmax[rs]=rmax[rs]=(set[rs]?0:(r-mid));
}
}
void build(int rt,int l,int r)
{
set[rt]=-1;
mmax[rt]=lmax[rt]=rmax[rt]=(r-l+1);
if(l==r)return ;
build(ls,l,mid);
build(rs,mid+1,r);
}
void ins(int rt,int l,int r,int L,int R,int w)
{
if(L<=l&&r<=R)
{
mmax[rt]=lmax[rt]=rmax[rt]=w?0:(r-l+1);
set[rt]=w;
return ;
}
pushdown(rt,l,r);
if(L<=mid)ins(ls,l,mid,L,R,w);
if(mid<R)ins(rs,mid+1,r,L,R,w);
pushup(rt,l,r);
}
int query(int rt,int l,int r,int w)
{
if(l==r)return l;
pushdown(rt,l,r);
if(mmax[ls]>=w) return query(ls,l,mid,w);
if((rmax[ls]+lmax[rs])>=w) return (mid-rmax[ls]+1);
return query(rs,mid+1,r,w);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int op,a,b;
build(1,1,n);
while(m--)
{
scanf("%d",&op);
if(op==1){
scanf("%d",&a);
if(mmax[1]<a)printf("0\n");
else
{
int _x=query(1,1,n,a);
printf("%d\n",_x);
ins(1,1,n,_x,_x+a-1,1);
}
}
else{
scanf("%d%d",&a,&b);
ins(1,1,n,a,a+b-1,0);
}
}
return 0;
}
hdu 2871
hotel加强版
删除操作要通过全段的update来进行
#include<stdio.h>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define mid ((l+r)>>1)
#define maxn 110000
int mmax[maxn<<2],lmax[maxn<<2],rmax[maxn<<2];
int lazy[maxn<<2];
struct block{
int begin,end;
};
vector<block>g;
void pushdown(int rt,int l,int r)
{
if(lazy[rt]!=-1)
{
lazy[ls]=lazy[rs]=lazy[rt];
lazy[rt]=-1;
mmax[ls]=lmax[ls]=rmax[ls]=lazy[ls]?0:(mid-l+1);
mmax[rs]=lmax[rs]=rmax[rs]=lazy[rs]?0:(r-mid);
}
}
void pushup(int rt,int l,int r)
{
lmax[rt]=lmax[ls];
rmax[rt]=rmax[rs];
if(lmax[ls]==(mid-l+1))lmax[rt]+=lmax[rs];
if(rmax[rs]==(r-mid))rmax[rt]+=rmax[ls];
mmax[rt]=max(mmax[ls],mmax[rs]);
mmax[rt]=max(mmax[rt],rmax[ls]+lmax[rs]);
}
void reset(int rt,int l,int r)
{
lazy[rt]=-1;
mmax[rt]=lmax[rt]=rmax[rt]=(r-l+1);
if(l==r)return ;
reset(ls,l,mid);
reset(rs,mid+1,r);
}
void update(int rt,int l,int r,int L,int R,int w)
{
if(L<=l&&r<=R){
mmax[rt]=rmax[rt]=lmax[rt]=w?0:(r-l+1);
lazy[rt]=w;
return ;
}
pushdown(rt,l,r);
if(L<=mid)update(ls,l,mid,L,R,w);
if(mid<R)update(rs,mid+1,r,L,R,w);
pushup(rt,l,r);
}
int query(int rt,int l,int r,int L,int R,int w)
{
if(l==r)return l;
pushdown(rt,l,r);
if(mmax[ls]>=w)return query(ls,l,mid,L,R,w);
else if((rmax[ls]+lmax[rs])>=w)
return mid-rmax[ls]+1;
else return query(rs,mid+1,r,L,R,w);
}
bool cmp(block a,block b){return a.begin<b.begin;}
int main()
{
// puts("");
int n,m,x;
char op[10];
while(~scanf("%d%d",&n,&m))
{
g.clear();
reset(1,1,n);
for(int i=0;i<m;++i)
{
scanf("%s",op);
if(op[0]=='R')
{
printf("Reset Now\n");
g.clear();
update(1,1,n,1,n,0);
}
else
{
scanf("%d",&x);
if(op[0]=='N')
{
if(mmax[1]<x)printf("Reject New\n");
else
{
int ans=query(1,1,n,1,n,x);
printf("New at %d\n",ans);
block s;
s.begin=ans;
s.end=ans+x-1;
update(1,1,n,ans,ans+x-1,1);
vector<block>::iterator it=upper_bound(g.begin(),g.end(),s,cmp);
g.insert(it,s);
//不能sort vector
}
}
else if(op[0]=='G')
{
if(x>g.size())
printf("Reject Get\n");
else
printf("Get at %d\n",g[x-1].begin);
}
else if(op[0]=='F')
{
block z;
z.begin=x;
z.end=x;
vector<block>::iterator it=upper_bound(g.begin(), g.end(),z,cmp);
int tmp=(int)(it-g.begin()-1);
if(tmp<0||g[tmp].end<x)
printf("Reject Free\n");
else
{
printf("Free from %d to %d\n",g[tmp].begin,g[tmp].end);
update(1,1,n,g[tmp].begin,g[tmp].end,0);
g.erase(g.begin()+tmp);
}
}
}
}
puts("");
}
return 0;
}
hdu 4614
双二分+线段树
#include<iostream>
#include<stdio.h>
#include<cstdio>
using namespace std;
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define mid ((l+r)>>1)
#define maxn 111111
int set[maxn<<2],sum[maxn<<2];
int m,n,t;
void pushup(int rt)
{
sum[rt]=sum[ls]+sum[rs];
}
void pushdown(int rt,int l,int r)
{
if(set[rt]!=-1)
{
set[ls]=set[rs]=set[rt];
sum[ls]=set[rt]==1?(mid-l+1):0;
sum[rs]=set[rt]==1?(r-mid):0;
set[rt]=-1;
}
}
void ins(int rt,int l,int r,int L,int R,int w)
{
if(L<=l&&r<=R)
{
set[rt]=w;
sum[rt]=w==1?(r-l+1):0;
return ;
}
pushdown(rt,l,r);
if(L<=mid)ins(ls,l,mid,L,R,w);
if(mid<R)ins(rs,mid+1,r,L,R,w);
pushup(rt);
}
int q2(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
return sum[rt];
pushdown(rt,l,r);
int ans=0;
if(L<=mid)ans+=q2(ls,l,mid,L,R);
if(mid<R)ans+=q2(rs,mid+1,r,L,R);
return ans;
}
int ansl,ansr;
void binl(int rr,int w)
{
int l=ansl,r=rr;
int xx=q2(1,1,n,ansl,r);
w=min(w,xx);
while(l<=r)
{
int _x=q2(1,1,n,mid,ansr);
// printf("%d %d %d\n",l,r,_x);
if(_x>=w){
ansl=mid;
l=mid+1;
}
else if(_x<w){
r=mid-1;
}
}
}
void binr(int w)
{
int l=ansl,r=n;
int xx=q2(1,1,n,ansl,n);
w=min(xx,w);
while(l<=r)
{
// printf("l:%d r:%d\n",l,r);
int _x=q2(1,1,n,ansl,mid);
if(_x>=w){
ansr=mid;
r=mid-1;
}
else
{
l=mid+1;
}
}
}
void build(int rt,int l,int r)
{
set[rt]=-1;
sum[rt]=(r-l+1);
if(l==r)return ;
build(ls,l,mid);
build(rs,mid+1,r);
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
int a,b,c;
build(1,1,n);
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
if(a==1)
{
int tmp=q2(1,1,n,b+1,n);
if(tmp==0)printf("Can not put any one.\n");
else
{
ansl=b+1;
binr(c);
binl(ansr,c);
printf("%d %d\n",ansl-1,ansr-1);
ins(1,1,n,ansl,ansr,0);
// printf("%d\n",q2(1,1,n,1,10));
}
}
else if(a==2)
{
// printf("%d\n",q2(1,1,n,1,10));
printf("%d\n",c-b+1-q2(1,1,n,b+1,c+1));
ins(1,1,n,b+1,c+1,1);
}
}
puts("");
}
return 0;
}
poj 1631
#include<stdio.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define mid ((l+r)>>1)
#define maxn 44444
int mmax[maxn<<2];
void ins(int rt,int l,int r,int L,int R,int w)
{
if(l==r)
{
mmax[rt]=w;
return ;
}
if(L<=mid)ins(ls,l,mid,L,R,w);
else if(mid<R)ins(rs,mid+1,r,L,R,w);
mmax[rt]=max(mmax[ls],mmax[rs]);
}
int query(int rt,int l,int r,int L,int R)
{
if(L<=l&&r<=R)
{
return mmax[rt];
}
int ans=0;
if(L<=mid)ans=max(ans,query(ls,l,mid,L,R));
if(mid<R)ans=max(ans,query(rs,mid+1,r,L,R));
return ans;
}
void build(int rt,int l,int r)
{
mmax[rt]=0;
if(l==r)return ;
build(ls,l,mid);
build(rs,mid+1,r);
}
int main()
{
int t,n,x,ans,tmp;
scanf("%d",&t);
while(t--)
{
ans=0;
scanf("%d",&n);
build(1,1,n);
for(int i=1;i<=n;++i){
scanf("%d",&x);
tmp=query(1,1,n,1,x);
// printf("tmp:%d\n",tmp);
ins(1,1,n,x,x,tmp+1);
ans=max(tmp+1,ans);
}
printf("%d\n",ans);
}
return 0;
}