[문제] [구간 트 리 / set] NKOJ 3480 [2015 다 교 합동 훈련 2] 아 Q 의 주차장

NKOJ 3480 [2015 다 교 합동 훈련 2] 아 Q 의 주차장 시간 제한: 20000 MS 공간 제한: 265536 KB
문 제 는 운전 면 허 를 갓 따 낸 KJ 가 항상 차 를 몰 고 드라이브 하 는 것 을 좋아한다 고 설명 했다. 놀다 가 아 Q 주차장 에 차 를 세 웠 다. 그녀 는 자신의 주차 수준 에 자신 이 있 지만 다른 사람의 주차 수준, 특히 Kelukin 을 안심 하지 못 했다.그래서 그녀 는 매번 자신의 사랑 의 차 를 다른 차 에서 가장 먼 곳 에 세 웠 다.KJ 는 자신의 이런 전략 이 매우 과학적 이 라 고 생각 하여 주차장 에 좌석 이 하나 있 는데 왼쪽 에서 오른쪽 까지 번호 가 1 부터 n 이 고 처음에 모두 비어 있 었 다 고 생각 하기 시작 했다.몇 개의 자동차 가 있 는데, 주차장 을 드 나 드 는 것 은 모두 m 회 이다.주차장 에 들 어 가 는 모든 자동차 에 대해 서 는 다른 차 와 의 거리 가 가장 작은 차 를 선택 하고 조건 에 맞 는 여러 개가 있 으 면 가장 왼쪽 하 나 를 선택한다.KJ 는 생각 하 다가 잠 이 들 었 습 니 다. 옆 에 있 는 Kelukin 은 그녀의 소원 을 들 어 주 려 고 했 습 니 다. 그러나 그 는 매우 게 을 러 서 스스로 손 을 쓰 려 고 하지 않 았 습 니 다. 그래서 이 문 제 를 당신 에 게 남 겨 주 었 습 니 다. KJ 의 이상 적 인 아 Q 주차장 에서 당신 의 차량 이 드 나 드 는 조작 서열 을 주 고 모든 차 의 좌석 번 호 를 차례대로 졌 습 니 다.
형식 첫 줄, 두 정수 n 과 m 를 입력 하여 주차장 크기 와 조작 수 를 표시 합 니 다.다음 m 줄 에서 각 줄 의 정수 F 와 x F 는 1 로 번호 가 x 인 차 가 주차장 에 들 어 가 는 것 을 나타 낸다.F 는 2 로 번호 가 x 인 차 가 주차장 밖으로 나 간 다 는 뜻 이다.합 법 적 인 조작 을 보장 한다. 즉, 주차장 을 나 가 는 차 는 반드시 현재 주차장 에 있다.주차장 안의 차 는 n 을 초과 하지 않 는 다.
출력 형식 은 모든 조작 1 에 대해 정 수 를 출력 하여 이 차 의 번 호 를 표시 합 니 다.
샘플 입력 7 11 1 15 1 123123 1 3 1 5 2 123123 2 15 1 21 2 3 1 6 1 7 8
샘플 출력 1, 7, 4, 2, 7, 4, 1, 3.
제시 [데이터 범위] 대 30% 의 데이터 n < = 1000, m < = 1000 대 60% 의 데이터 n < = 20000, m < = 2000 대 100% 의 데이터 n, m < = 20000, 차 의 번 호 는 10 ^ 6 보다 작 습 니 다.
출처: BS
사고: 법 1: 선분 나무, 1. 유지 보수 단점 1 또는 0 은 주차 여 부 를 나타 낸다.왼쪽 에서 오른쪽으로 얻 을 수 있 는 가장 효과 적 인 구간, 오른쪽 에서 왼쪽으로 얻 을 수 있 는 가장 효과 적 인 구간, 전체 얻 을 수 있 는 가장 효과 적 인 구간 을 유지 합 니 다.2. 유효 구간 정의: 첫 번 째 키워드: 주차 후 가장 가 까 운 차 와 의 거 리 는 클 수록 좋다.두 번 째 키워드: 왼쪽 점 의 위 치 는 작 을 수록 좋다.세 번 째 키워드: 구간 총 길이, 길 수록 좋 습 니 다.3. 조작 조작 1. 1 시작 구간, n 끝 구간, max 구간 에서 누가 b 의 위 치 를 얻 을 수 있 는 지 판단 한다 (첫 번 째, 꼬리 구간 이 특수 하 다).조작조작 2, 점 조작 0.
#include
#include
#include
using namespace std;
#define END fclose(stdin),fclose(stdout);return 0
const int need=200004;
const int needk=1e6+7;

//....................................................
inline void in_(int & d)
{
    char t=getchar();
    while(t<'0'||t>'9') t=getchar();
    for(d=0;!(t<'0'||t>'9');t=getchar()) d=(d<<1)+(d<<3)+t-'0';
}
char o[100];
inline void out_(int x)
{   
    int l=1; 
    if(!x) putchar('0');  
    for(;x;x/=10) o[l++]=x%10+'0';  
    for(l--;l;l--)putchar(o[l]);  
    putchar('
'
); } //.................................................... struct yf { int a,b; inline int loc(){return (a+b)>>1;} inline int len(){return b-a+1;} inline int len2(){return loc()-a+1;} inline friend bool operator>(yf a,yf b) { if(a.len2()==b.len2()) { if(a.a==b.a) return a.len()>b.len(); return a.areturn a.len2()>b.len2(); } inline yf operator+(const yf& b) { yf ans; ans.a=a,ans.b=b.b; return ans; } }; struct fy { int a,b,val; yf fl,fr,max; inline int len(){return b-a+1;} } w[need<<3]; #define ls (s<<1) #define rs ((s<<1)|1) inline void NBHB(int s) { if(w[s].len()==1) { if(w[s].val==0) { w[s].fl.b=w[s].a; w[s].max=w[s].fr=w[s].fl; } else { w[s].fl.b=w[s].a-1; w[s].fr.a=w[s].b+1; w[s].max=w[s].fl; } return ; } if(w[rs].max>w[ls].max) w[s].max=w[rs].max; else w[s].max=w[ls].max; if(w[ls].fr+w[rs].fl>w[s].max) w[s].max=w[ls].fr+w[rs].fl; if(w[ls].len()==w[ls].fl.len()) { w[s].fl.b=w[ls].a+w[ls].fl.len()+w[rs].fl.len()-1; } else w[s].fl.b=w[ls].fl.b; if(w[rs].len()==w[rs].fr.len()) { w[s].fr.a=w[rs].b-w[rs].fr.len()-w[ls].fr.len()+1; } else w[s].fr.a=w[rs].fr.a; } void build(int s,int l,int r) { w[s].a=w[s].fl.a=l,w[s].b=w[s].fr.b=r; if(l==r) { w[s].val=0; NBHB(s); return ; } build(ls,l,(l+r)>>1),build(rs,(l+r)/2+1,r); NBHB(s); } int d,val; int loc[needk]; inline void change(int s) { if(w[s].len()==1) { w[s].val=val; NBHB(s); return ; } int mid=(w[s].b+w[s].a)>>1; if(d<=mid) change(ls); else change(rs); NBHB(s); } //.................................................... int main() { int n,m;scanf("%d%d",&n,&m); build(1,1,n); for(int i=1,a,b,lenl,lenr,lenm,temploc,templen;i<=m;i++) { in_(a),in_(b); if(a==1) { temploc=w[1].max.loc(); lenm=templen=w[1].max.len2(); lenl=w[1].fl.len(); lenr=w[1].fr.len(); if(lenl>=lenm) temploc=1,templen=lenl; if(lenr>templen) temploc=n; loc[b]=temploc; out_(loc[b]);//printf("%d
",loc[b]);
d=loc[b],val=1; change(1); } else { d=loc[b],val=0; change(1); loc[b]=0; } } }

법 2: set 는 조작 1 에 대해 매번 가장 효과 적 인 구간 만 선택 하고 set 또는 우선 대기 열 을 사용 하 는 것 을 고려 합 니 다.한 점 을 삭제 하면 두 구간 으로 변 한다. 즉, 하 나 를 삭제 하고 두 개 를 추가 하 는 것 이다.조작 2 에 대해 서 는 매번 두 구간 을 합 쳐 야 한다. 즉, 두 개 를 삭제 하고 하 나 를 추가 해 야 한다.지정 한 구간 을 삭제 하기 위해 서 는 우선 대기 열 이 아 닌 set 를 사용 합 니 다.
또 하나의 set 를 열 어 주차 한 위 치 를 순서대로 기록 하여 합병 할 때 합병 해 야 할 두 구간 을 쉽게 찾 을 수 있 습 니 다.
#include
#include
#include
#include
#include
#include
using namespace std;
const int need=1e6+7;

int n,m;
int loc_[need];
//.........................................................
struct fy
{
    int a,b;
    inline int loc(){return (a+b)>>1;}
    inline int len() const
    {
        if(a==1) return b;
        if(b==n) return b-a+1;
        return (a+b)/2-a+1;
    }
};
struct yf{
inline bool operator() (const fy &a,const fy &b)
{
    if(a.len()==b.len())return a.areturn a.len()>b.len();
} };

typedef set sf;
sf s;
sf::iterator sit;
typedef set<int> si;
si loc;
si::iterator lit,llnt,rlnt;
//.........................................................
inline void in_(int & d) 
{
    char t=getchar();
    while(t<'0'||t>'9') t=getchar();
    for(d=0;!(t<'0'||t>'9');t=getchar()) d=(d<<1)+(d<<3)+t-'0';
}
//.........................................................

int main()
{
    scanf("%d%d",&n,&m);
    s.insert((fy){1,n});
    loc.insert(0),loc.insert(n+1);
    fy temp,temp1;
    for(int i=1,a,b,k,ans;i<=m;i++)
    {
        in_(a),in_(b);
        if(a==1)
        {
            temp=*s.begin();
            s.erase(s.begin());
            if(temp.a==1) 
            {
                ans=1;
                temp.a=2;
                s.insert(temp);
            }
            else if(temp.b==n)
            {
                ans=n;
                temp.b=n-1;
                s.insert(temp);
            }
            else
            {
                ans=temp.loc();
                temp1=temp;
                temp.b=ans-1;
                temp1.a=ans+1;
                s.insert(temp),s.insert(temp1);
            }
            printf("%d
"
,loc_[b]=ans); loc.insert(ans); } else { lit=loc.find(loc_[b]); temp.a=*(--lit)+1,temp.b=loc_[b]-1; s.erase(temp); temp1.a=loc_[b]+1,temp1.b=*(++++lit)-1; s.erase(temp1); temp.b=temp1.b; s.insert(temp); loc.erase(loc_[b]);// erasse loc_[b]=0; } } }

좋은 웹페이지 즐겨찾기