hdu4095 Very Boring Homework(笛卡尔树+模拟)

题目请戳这里

题目大意:给一个数字序列1-n,按输入次序建一颗BST,然后按照题目描述,输出任意给定矩形的树。给了5条描述,感觉很复杂的样子,然后看这样例自己yy了一下,就那么回事吧。设树高d,n个点,那么这棵树在n*(2d-1)的矩形区域内。n是列,2d-1是行。每个节点只能在一列出现。具体不好描述,还是自己拿笔画画吧。

题目分析:首先要画出这棵树,先要建树。此题的n有100000,如果直接模拟建,最坏复杂度O(n^2),无法忍受。随便画出一颗这样的树,如果给每个点出现的次序标号会发现,这颗树中点出现的次序标号构成了一个小堆。小堆。。。BST。。。。想到了什么?没错,笛卡尔树!

什么是笛卡尔树?

看出这是一颗笛卡尔树,那么就可以O(n)时间建树了。建完树后bfs一遍求出所有点的深度(dfs会爆栈),然后就是模拟了。

trick:1:给的矩形可能爆int。

2:给的矩形可能超出树所在的矩形,那么对于超出的部分,空格照样输出!!!!!!!!(此处PE无数次!!!)(当然前提还是此行有非空白符)


ps:竟然凭一己之力,将此题的ac率怒降10+个百分点!!

pps:太sb了啊啊啊

详情请见代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
const int N = 100005;
typedef __int64 ll;
struct node
{
    int l,r,f,key,value;
    friend bool operator <(const struct node a,const struct node b)
    {
        return a.key < b.key;
    }
}lcm[N];
int n,m,root,num,maxdp;
int stack[N];
int dep[N];

int head[N];
struct nd
{
    int to,next;
}g[N];
void add(int s,int e)
{
    g[num].to = e;
    g[num].next = head[s];
    head[s] = num ++;
}
int build()
{
    int top = -1;
    int i,j;
    top = -1;
    for(i = 1;i <= n;i ++)
    {
        j = top;
        while(j >= 0 && lcm[stack[j]].value > lcm[i].value)
            j --;
        if(j != -1)
        {
            lcm[i].f = stack[j];
            lcm[stack[j]].r = i;
        }
        if(j < top)
        {
            lcm[stack[j + 1]].f = i;
            lcm[i].l = stack[j + 1];
        }
        stack[++ j] = i;
        top = j;
    }
    lcm[stack[0]].f = -1;
    return stack[0];
}
void bfs(int root,int dp)
{
    int front,rear;
    front = rear = 0;
    dep[root] = dp;
    add(dp,root);
    stack[rear ++] = root;
    while(front != rear)
    {
        int cur = stack[front ++];
        if(lcm[cur].l > 0)
        {
            dep[lcm[cur].l] = dep[cur] + 1;
            add(dep[cur] + 1,lcm[cur].l);
            stack[rear ++] = lcm[cur].l;
            if(maxdp < dep[cur] + 1)
                maxdp = dep[cur] + 1;
        }
        if(lcm[cur].r > 0)
        {
            dep[lcm[cur].r] = dep[cur] + 1;
            add(dep[cur] + 1,lcm[cur].r);
            stack[rear ++] = lcm[cur].r;
            if(maxdp < dep[cur] + 1)
                maxdp = dep[cur] + 1;
        }
    }
}
char ans[205][N + 205];
void print(ll l,ll r,ll u,ll d)
{
    ll i,j,k;
    for(i = u;i <= d;i ++)
    {
        memset(ans[i - u],0,sizeof(ans[i - u]));
        if(i & 1)
        {
            for(j = head[(i + 1)>>1];~j;j = g[j].next)
            {
                ans[i - u][g[j].to] = 'o';
                if(lcm[g[j].to].l != -1)
                {
                    ans[i - u][lcm[g[j].to].l] = '+';
                    for(k = lcm[g[j].to].l + 1;k < g[j].to;k ++)
                        ans[i - u][k] = '-';
                }
                if(lcm[g[j].to].r != -1)
                {
                    ans[i - u][lcm[g[j].to].r] = '+';
                    for(k = lcm[g[j].to].r - 1;k > g[j].to;k --)
                        ans[i - u][k] = '-';
                }
            }
        }
        else
        {
            for(j = head[i>>1];~j;j = g[j].next)
            {
                if(lcm[g[j].to].l != -1)
                    ans[i - u][lcm[g[j].to].l] = '|';
                if(lcm[g[j].to].r != -1)
                    ans[i - u][lcm[g[j].to].r] = '|';
            }
        }
    }
    for(i = 0;i <= d - u;i ++)
    {
        bool fuck = false;
        for(j = l;j <= r;j ++)
            if(ans[i][j])
            {
                fuck = true;
                break;
            }
        if(fuck == false)
            continue;
        for(j = l;j <= r;j ++)
            if(ans[i][j])
                putchar(ans[i][j]);
            else
                putchar(' ');
        putchar(10);
    }
}

void rush()
{
    ll l,r,u,d;
    scanf("%d",&m);
    while(m --)
    {
        scanf("%I64d%I64d%I64d%I64d",&u,&l,&d,&r);
        d = u + d - 1;
        r = l + r - 1;
//        if(r > n)此句是万恶之源!!!!!!!!!!!!
//            r = n;
        if(d > maxdp + maxdp-1)
            d = maxdp + maxdp-1;
        print(l,r,u,d);
        printf("\n");
    }
}
int main()
{
    int i,t,cas = 0;
    scanf("%d",&t);
    while(t --)
    {
        scanf("%d",&n);
        for(i = num = 1;i <= n;i ++)
        {
            lcm[i].l = lcm[i].r = lcm[i].f = -1;
            head[i] = -1;
            scanf("%d",&lcm[i].key);
            lcm[i].value = i;
        }
        sort(lcm + 1,lcm + 1 + n);
        root = build();
        maxdp = 1;
        bfs(root,1);
        printf("Case #%d:\n",++cas);
        rush();
    }
    return 0;
}
//812MS	14668K


你可能感兴趣的:(数据结构,模拟)