@iamtts
2017-05-14T23:38:01.000000Z
字数 3488
阅读 1082
1.入住,给出人数k,要求连续k间空房,若无法满足则输出0,满足则输出满足条件且最左边的房间号
2.清空,从房间a到b全部清空
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 100000 + 5;
struct node
{
int lsum,rsum,sum,l,r,flag;
} tree[N*4];
inline int MAX(int a,int b,int c)
{
return max(a,max(b,c));
}
void push_up(int now)
{
tree[now].lsum=tree[now<<1].lsum;
tree[now].rsum=tree[now<<1|1].rsum;
if (tree[now].lsum==tree[now<<1].r-tree[now<<1].l+1) tree[now].lsum+=tree[now<<1|1].lsum;
if (tree[now].rsum==tree[now<<1|1].r-tree[now<<1|1].l+1) tree[now].rsum+=tree[now<<1].rsum;
tree[now].sum=MAX(tree[now<<1].sum,tree[now<<1|1].sum,tree[now<<1].rsum+tree[now<<1|1].lsum);
}
void push_down(int now)
{
if (tree[now].flag!=-1)
{
tree[now<<1].flag=tree[now<<1|1].flag=tree[now].flag;
if (tree[now].flag==1)
{
tree[now<<1].sum=tree[now<<1].lsum=tree[now<<1].rsum=0;
tree[now<<1|1].sum=tree[now<<1|1].lsum=tree[now<<1|1].rsum=0;
}
else
{
tree[now<<1].sum=tree[now<<1].lsum=tree[now<<1].rsum=tree[now<<1].r-tree[now<<1].l+1;
tree[now<<1|1].sum=tree[now<<1|1].lsum=tree[now<<1|1].rsum=tree[now<<1|1].r-tree[now<<1|1].l+1;
}
tree[now].flag=-1;
}
}
void build_tree(int l,int r,int now)
{
tree[now].l=l;
tree[now].r=r;
tree[now].flag=-1;
tree[now].lsum=tree[now].rsum=tree[now].sum=r-l+1;
if (l==r) return;
int mid=(r+l)/2;
build_tree(l,mid,now<<1);
build_tree(mid+1,r,now<<1|1);
}
int query_tree(int l,int r,int now,int x)
{
if (r==l) return l;
int mid=(l+r)/2;
push_down(now);
if (tree[now<<1].sum>=x) return query_tree(l,mid,now<<1,x);
else if (tree[now<<1].rsum+tree[now<<1|1].lsum>=x) return mid-tree[now<<1].rsum+1;
else return query_tree(mid+1,r,now<<1|1,x);
}
void update(int l,int r,int now,int x)
{
if (tree[now].l==l &&tree[now].r==r)
{
tree[now].flag=x;
if (x)
{
tree[now].sum=tree[now].lsum=tree[now].rsum=0;
}
else
{
tree[now].sum=tree[now].lsum=tree[now].rsum=r-l+1;
}
return;
}
push_down(now);
int mid=(tree[now].r+tree[now].l)/2;
if (mid>=r) update(l,r,now<<1,x);
else if (mid+1<=l) update(l,r,now<<1|1,x);
else
{
update(l,mid,now<<1,x);
update(mid+1,r,now<<1|1,x);
}
push_up(now);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
build_tree(1,n,1);
for (int i=1; i<=m; i++)
{
int judge;
scanf("%d",&judge);
if (judge==1)
{
int num;
scanf("%d",&num);
if (tree[1].sum<num) cout<<0<<endl;
else
{
int x=query_tree(1,n,1,num);
printf("%d\n",x);
update(x,x+num-1,1,1);
}
}
else
{
int x,y;
scanf("%d%d",&x,&y);
update(x,x+y-1,1,0);
}
}
}
return 0;
}
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
#define N 100005
int stmax[N][21],stmin[N][21];
int a[N];
int t,q,n,k;
int x,y;
void init()
{
for (int i=1;i<=n;i++)
{
stmax[i][0]=stmin[i][0]=a[i];
}
for (int j=1;(1<<j) <= n;j++)
for (int i=1;i+(1<<j)-1<=n;i++)
{
stmax[i][j]=max(stmax[i][j-1],stmax[i+(1<<(j-1))][j-1]);
stmin[i][j]=min(stmin[i][j-1],stmin[i+(1<<(j-1))][j-1]);
}
}
bool ok(int L,int R)
{
int kk= log2(R - L + 1.0);
int Max=max(stmax[L][kk],stmax[R-(1<<kk)+1][kk]);
int Min=min(stmin[L][kk],stmin[R-(1<<kk)+1][kk]);
//printf("%d~%d:%d\n",L,R,Max-Min);
if (Max-Min<k) return true;
return false;
}
int main()
{
scanf("%d",&t);
while (t--)
{
long long cnt=0;
scanf("%d%d",&n,&k);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
init();
for (int i=1;i<=n;i++)
{
long long ub=n,lb=i,mid;
while (ub-1>lb)
{
mid=(ub+lb)/2;
if (ok(i,mid)) lb=mid;
else ub=mid;
}
if (ok(i,ub)) cnt+=ub-i+1;
else cnt+=lb-i+1;
//printf("%d\n",mid-i+1);
}
printf("%lld\n",cnt);
}
return 0;
}