【洛谷 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\n",cnt[i]);
        if(init[i][0]==1) printf("%d\n",sum);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值