【洛谷 2161】 [Shoi2009]Booking 会场预约

洛谷真良心 这是BZOJ的权限题.....
明明树状数组很好做 我偏偏用线段树
明明在线很好做 我偏偏离线
.
.
.
.

简直作死 又调试了一下午 !!

线段树 最小值 区间标记时注意下!!! 宁可多取几次min 做几个无用功没事 说不定少了那个就wa上半天!!!

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define MAXN 1000000
using namespace std;
int init[200000+1][3]; //0 A B   1s 2t
bool b[200000+1];
int cnt[200000+1];
int n;
int a[100000*4],m[100000*4];
void Pushdown(int now)
{
	m[now*2]=min(m[now*2],m[now]); a[now*2]=min(a[now*2],m[now*2]);
	m[now*2+1]=min(m[now*2+1],m[now]); a[now*2+1]=min(a[now*2+1],m[now*2+1]);
//	m[now]=100000000;
}
void Change(int now,int L,int R,int s,int t,int k)
{
//	cout<<now<<' '<<a[now]<<' '<<L<<' '<<R<<' '<<s<<' '<<t<<' '<<k<<endl;
	
	if(s<=L&&R<=t) 
	{
		m[now]=min(m[now],k);
		a[now]=m[now];
		return ;
	}
	if(m[now]!=100000000)
		Pushdown(now);
	int mid=(L+R)/2;
	if(s<=mid) Change(now*2,L,mid,s,t,k);
	if(mid+1<=t) Change(now*2+1,mid+1,R,s,t,k);
	a[now]=min(a[now*2],a[now*2+1]);
}
int Query(int now,int L,int R,int s,int t)
{
	//cout<<now<<' '<<a[now]<<' '<<L<<' '<<R<<' '<<s<<' '<<t<<' '<<endl;
	
	if(s<=L&&R<=t) return a[now];
	if(m[now]!=100000000)
		Pushdown(now);
	int mid=(L+R)/2,ans=100000000;
	if(s<=mid) ans=min(ans,Query(now*2,L,mid,s,t));
	if(mid+1<=t) ans=min(ans,Query(now*2+1,mid+1,R,s,t));
	return ans;
}
int main()
{
//	fr0eopen("a.in","r",stdin);
//	fr0eopen("test.out","w",stdout);
	for(int i=1;i<100000*4;i++) m[i]=100000000,a[i]=100000000;
	cin>>n; char c;
	for(int i=1;i<=n;i++)
	{
		cin>>c;
		if(c=='A') init[i][0]=0,scanf("%d %d",&init[i][1],&init[i][2]);
		else init[i][0]=1;
	}
	for(int i=n;i>=1;i--)
	if(init[i][0]==0)
	{
		int tmp=Query(1,1,100000,init[i][1],init[i][2]);// cout<<i<<' '<<tmp<<endl;
		if(tmp==100000000)
			b[i]=true;
		else 
			cnt[tmp]++;
		Change(1,1,100000,init[i][1],init[i][2],i);		
	}
	int sum=0;
	for(int i=1;i<=n;i++)
	{
		
		if(init[i][0]==0) sum=sum+1-cnt[i],printf("%d
",cnt[i]);
		if(init[i][0]==1) printf("%d
",sum);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/ofsxb/p/5116650.html