HDU 4417 슈퍼 마리 오 (나무 구분) \ # by zh

경기 할 때 이 문 제 를 보고 많은 조회 조작 이 있 었 습 니 다. 마치 라인 트 리 문제 인 것 같 습 니 다. 과감하게 라인 트 리 로 썼 습 니 다. 그리고 비 극적인 TLE 입 니 다..........................................................................그러나 아직 이 데이터 구조의 구체 적 인 실현 을 모 르 니 저녁 에 연구 해 야 한다.
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
#define M 100001
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
struct Seg_Tree
{
    int left,right;
    int mid()
    {
        return (left + right) >> 1;
    }
} tt[M<<2];
int len;
int sorted[M];
int toLeft[20][M];
int val[20][M];

void build(int l,int r,int d,int idx)
{
    tt[idx].left = l;
    tt[idx].right = r;
    if(tt[idx].left == tt[idx].right)	return ;
    int mid = tt[idx].mid();
    int lsame = mid - l + 1;//lsame   val_mid        
    for(int i = l ; i <= r ; i ++)
    {
        if(val[d][i] < sorted[mid])
        {
            lsame --;//       (mid - l + 1)    val_mid,        val_mid   
        }
    }
    int lpos = l;
    int rpos = mid+1;
    int same = 0;
    for(int i = l ; i <= r ; i ++)
    {
        if(i == l)
        {
            toLeft[d][i] = 0;//toLeft[i]  [ tt[idx].left , i ]            
        }
        else
        {
            toLeft[d][i] = toLeft[d][i-1];
        }
        if(val[d][i] < sorted[mid])
        {
            toLeft[d][i] ++;
            val[d+1][lpos++] = val[d][i];
        }
        else if(val[d][i] > sorted[mid])
        {
            val[d+1][rpos++] = val[d][i];
        }
        else
        {
            if(same < lsame)  // lsame        
            {
                same ++;
                toLeft[d][i] ++;
                val[d+1][lpos++] = val[d][i];
            }
            else
            {
                val[d+1][rpos++] = val[d][i];
            }
        }
    }
    build(l,mid,d+1,LL(idx));
    build(mid+1,r,d+1,RR(idx));
}

int query(int l,int r,int k,int d,int idx)
{
    if(l == r)
    {
        return val[d][l];
    }
    int s;//s  [ l , r ]        
    int ss;//ss   [tt[idx].left , l-1 ]        
    if(l == tt[idx].left)
    {
        s = toLeft[d][r];
        ss = 0;
    }
    else
    {
        s = toLeft[d][r] - toLeft[d][l-1];
        ss = toLeft[d][l-1];
    }
    if(s >= k)  //   k     ,          k 
    {
        int newl = tt[idx].left + ss;
        int newr = tt[idx].left + ss + s - 1;//         
        return query(newl,newr,k,d+1,LL(idx));
    }
    else
    {
        int mid = tt[idx].mid();
        int bb = l - tt[idx].left - ss;//bb   [tt[idx].left , l-1 ]        
        int b = r - l + 1 - s;//b   [l , r]        
        int newl = mid + bb + 1;
        int newr = mid + bb + b;
        return query(newl,newr,k-s,d+1,RR(idx));
    }
}
int main()
{
    //freopen("input.txt","r",stdin);
    int n,m,t;
    scanf("%d",&t);
    for(int cas=1; cas<=t; cas++)
    {
        scanf("%d %d",&n,&m);
        printf("Case %d:
",cas); for(int i = 1 ; i <= n ; i++) { scanf("%d",&val[0][i]); sorted[i] = val[0][i]; } sort(sorted+1,sorted+n+1); build(1,n,0,1); while(m--) { int a,b,h; scanf("%d %d %d",&a,&b,&h); int low=1,high=b-a+1,mid; while(low<=high) { mid=(high+low)>>1; if(query(a+1,b+1,mid,0,1)<=h) low=mid+1; else high=mid-1; } printf("%d
",low-1); } } return 0; }

좋은 웹페이지 즐겨찾기