约会安排[HDU

约会安排[HDU - 4553]( Problem - 4553 (hdu.edu.cn) ) T6 D24

思路:

线段树区间合并。线段树维护NS和DS的左连续区间和右连续区间,更新时按优先级顺序更新,学习>NS>DS

/*
               #########                       
              ############                     
              #############                    
             ##  ###########                   
            ###  ###### #####                  
            ### #######   ####                 
           ###  ########## ####                
          ####  ########### ####               
        #####   ###########  #####             
       ######   ### ########   #####           
       #####   ###   ########   ######         
      ######   ###  ###########   ######       
     ######   #### ##############  ######      
    #######  ##################### #######     
    #######  ##############################    
   #######  ###### ################# #######   
   #######  ###### ###### #########   ######   
   #######    ##  ######   ######     ######   
   #######        ######    #####     #####    
    ######        #####     #####     ####     
     #####        ####      #####     ###      
      #####      ;###        ###      #        
        ##       ####        ####     

HDU - 4553 真折磨啊         
*/
#include<iostream>
#include<algorithm>
#include<math.h>
#include<string>
#include<string.h>
#define ll long long 
#define ls (p<<1)
#define rs ((p<<1)|1)
#define mid ((t[p].l+t[p].r)>>1) 
using namespace std;
int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void Prin(int x){if(x < 0){putchar('-');x = -x;}if(x > 9) Prin(x / 10);putchar(x % 10 + '0');}
const int qs=2e5+7;
struct Tree{
	int l,r,dl,dr,nl,nr,dsum,nsum,add,ann;
	#define l(x) t[x].l
	#define r(x) t[x].r
	#define dl(x) t[x].dl
	#define dr(x) t[x].dr
	#define nl(x) t[x].nl
	#define nr(x) t[x].nr
	#define dsum(x) t[x].dsum
	#define nsum(x) t[x].nsum
	#define add(x) t[x].add
	#define ann(x) t[x].ann
}t[qs<<2];
void pushup(int p){
	dl(p)=dl(ls)+(dl(ls)==r(ls)-l(ls)+1 ? dl(rs) : 0);
	dr(p)=dr(rs)+(dr(rs)==r(rs)-l(rs)+1 ? dr(ls) : 0);
	dsum(p)=max(max(dsum(ls),dsum(rs)),dr(ls)+dl(rs));
	nl(p)=nl(ls)+(nl(ls)==r(ls)-l(ls)+1 ? nl(rs) : 0);
	nr(p)=nr(rs)+(nr(rs)==r(rs)-l(rs)+1 ? nr(ls) : 0);
	nsum(p)=max(max(nsum(ls),nsum(rs)),nr(ls)+nl(rs));
}
void build(int p,int l,int r){
	l(p)=l,r(p)=r;
	add(p)=ann(p)=-1;
	if(l==r) {
		dl(p)=dr(p)=dsum(p)=1;
		nl(p)=nr(p)=nsum(p)=1;
		return;
	}
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(p);
}
void down(int p){
	if(add(p)!=-1){
		dl(ls)=dr(ls)=dsum(ls)=(r(ls)-l(ls)+1)*add(p);
		dl(rs)=dr(rs)=dsum(rs)=(r(rs)-l(rs)+1)*add(p);
		add(ls)=add(rs)=add(p);
	}
	
	if(ann(p)!=-1){
		nl(ls)=nr(ls)=nsum(ls)=(r(ls)-l(ls)+1)*ann(p);
		nl(rs)=nr(rs)=nsum(rs)=(r(rs)-l(rs)+1)*ann(p);
		ann(ls)=ann(rs)=ann(p);
	}
	add(p)=ann(p)=-1;
}
void update(int p,int l,int r,int k,int nk){
	down(p);	
	if(l<=l(p)&&r>=r(p)){
		dl(p)=dr(p)=dsum(p)=(r(p)-l(p)+1)*k;
		if(nk!=-1) nl(p)=nr(p)=nsum(p)=(r(p)-l(p)+1)*nk;
		add(p)=k;
		ann(p)=nk;
			return;
	}	
	if(l<=mid) update(ls,l,r,k,nk);
	if(r>mid) update(rs,l,r,k,nk);
	pushup(p);
}
int ask(int p,int len,int k){
	down(p);
	if(l(p)==r(p)) return 1;
	if(k==1){
		if(dsum(ls)>=len) return ask(ls,len,k);
		else if(dl(rs)+dr(ls)>=len) return mid-dr(ls)+1;
		else return ask(rs,len,k);
	}
	else{
		if(nsum(ls)>=len) return ask(ls,len,k);
		else if(nl(rs)+nr(ls)>=len) return mid-nr(ls)+1;
		else return ask(rs,len,k);
	}
	return 0;
} 
int T,n,q;
int main(){
	T=read();
	for(int ti=1;ti<=T;++ti){
	printf("Case %d:
",ti);
	n=read(),q=read();
	build(1,1,n);
	while(q--){
		string s;
		int l,len,r;
		cin>>s;
		if(s=="DS"){
			len=read();
			if(dsum(1)<len){
				printf("fly with yourself
");
				continue;
			}
			int ans=ask(1,len,1);
			printf("%d,let's fly
",ans);
			update(1,ans,ans+len-1,0,-1);
		}
		else if(s=="NS"){
			len=read();
			if(dsum(1)<len){
				if(nsum(1)<len){
					printf("wait for me
");
					continue;
				}
				int ans=ask(1,len,2);
				printf("%d,don't put my gezi
",ans);
				update(1,ans,ans+len-1,0,0);
				continue;
			}
			int ans=ask(1,len,1);
			printf("%d,don't put my gezi
",ans);
			update(1,ans,ans+len-1,0,0);
		}
		else{
			l=read(),r=read();
			update(1,l,r,1,1);
			printf("I am the hope of chinese chengxuyuan!!
");
		}
	}
}	
	return 0;
}
原文地址:https://www.cnblogs.com/Suki-Sugar/p/15226178.html