HDU - 4614(线段树+区间更新)
HDU - 4614(线段树+区间更新)
参考博客:点我
每次查询某个区间【X, N】这个区间是否能放一朵花,若能放就返回最后一朵花的位置。若不能放则返回-1。 每次线段树向下递归的时候,判断一下左边空花瓶的数量是否>=f, 若大于代表左边区间的花瓶就可以放完,那么直接递归左边区间,反之则将花的数量-左边区间空花瓶的数量,然后递归右区间。类似主席树求第K大的思想。最后到根节点再判断一下该节点是否能够放花,若不能那么只能又去找另一区间。比如递归了右区间,但是发现右边区间已经无法放了,那么只能去左边区间找最后一朵花的位置。
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <math.h>
#include <string>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#define maxn 50005
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int mod = 1e9 + 7;
using namespace std;
int sum[maxn<<2],lazy[maxn<<2];
void build(int node,int l,int r){
if(l==r){
sum[node]=1;
lazy[node]=-1;
return ;
}
int mid=(l+r)>>1;
build(node<<1,l,mid);
build(node<<1|1,mid+1,r);
lazy[node]=-1;
sum[node]=sum[node<<1]+sum[node<<1|1];
}
void pushdown(int node,int l,int r){
if(lazy[node]==-1) return ;
if(lazy[node]==0){
lazy[node<<1]=lazy[node<<1|1]=0;
sum[node<<1]=sum[node<<1|1]=0;
}
else if(lazy[node]==1){
int mid=(l+r)>>1;
sum[node<<1]=mid-l+1;
sum[node<<1|1]=r-mid;
lazy[node<<1]=lazy[node<<1|1]=1;
}
lazy[node]=-1;
}
void update(int node,int start,int ends,int l,int r,int val){
if(start>=l&&ends<=r){
if(val==1) sum[node]=ends-start+1;
else sum[node]=0;
lazy[node]=val;
return ;
}
int mid=(start+ends)>>1;
pushdown(node,start,ends);
if(l<=mid) update(node<<1,start,mid,l,r,val);
if(mid<r) update(node<<1|1,mid+1,ends,l,r,val);
sum[node]=sum[node<<1]+sum[node<<1|1];
}
int query(int node,int start,int ends,int l,int r){
if(start>=l&&ends<=r) return sum[node];
int mid=(start+ends)>>1;
pushdown(node,start,ends);
int ans=0;
if(l<=mid) ans+=query(node<<1,start,mid,l,r);
if(r>mid) ans+=query(node<<1|1,mid+1,ends,l,r);
return ans;
}
int solve(int node,int start,int ends,int l,int r,int k){
if(start==ends){
if(sum[node]==0) return -1;
if(sum[node]==1) return start;
}
pushdown(node,start,ends);
int ln=0,ans=-1;
int mid=(start+ends)>>1;
if(l<=mid) ln=query(node<<1,start,mid,l,mid);
if(k>ln) ans=solve(node<<1|1,mid+1,ends,l,r,k-ln);
else ans=solve(node<<1,start,mid,l,r,k);
if(ans==-1){
if(ln==0) return -1;
ans=solve(node<<1,start,mid,l,r,k);
}
return ans;
}
int main()
{
int t;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
build(1,1,n);
for(int i=0;i<m;i++){
int x,y,k;
scanf("%d%d%d",&k,&x,&y);
if(k==1){
x++;
int ends=solve(1,1,n,x,n,y);
if(ends==-1) printf("Can not put any one.\n");
else{
int start=solve(1,1,n,x,n,1);
printf("%d %d\n",start-1,ends-1);
update(1,1,n,start,ends,0);
}
}
else{
x++,y++;
int t=query(1,1,n,x,y);
update(1,1,n,x,y,1);
printf("%d\n",y-x-t+1);
}
}
printf("\n");
}
return 0;
}
题解 文章被收录于专栏
主要写一些题目的题解