@iamtts
2017-05-14T15:38:01.000000Z
字数 3488
阅读 1234
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 100005int 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;}